[
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file\n\nversion: 2\nupdates:\n  - package-ecosystem: \"gomod\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n    groups:\n      k8s-deps:\n        patterns:\n          - \"*k8s.io*\"\n      envoy-deps:\n        patterns:\n          - \"*envoyproxy*\"\n    labels:\n      - \"area/dependency\"\n      - \"ok-to-test\"\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    labels:\n      - \"area/dependency\"\n      - \"ok-to-test\"\n\n  - package-ecosystem: \"docker\"\n    directories:\n      - \"**/*\"\n    schedule:\n      interval: \"weekly\"\n    labels:\n      - \"area/dependency\"\n      - \"ok-to-test\"\n"
  },
  {
    "path": ".github/workflows/bats.yml",
    "content": "name: bats\n\non:\n  push:\n    branches:\n      - 'main'\n    tags:\n      - 'v*'\n  pull_request:\n    branches: [ main ]\n  workflow_dispatch:\n\nenv:\n  GO_VERSION: \"1.25\"\n  K8S_VERSION: \"v1.35.0\"\n  KIND_VERSION: \"v0.31.0\"\n\njobs:\n  bats_tests:\n    runs-on: ubuntu-22.04\n    name: Bats e2e tests\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: Setup Bats and bats libs\n        id: setup-bats\n        uses: bats-core/bats-action@77d6fb60505b4d0d1d73e48bd035b55074bbfb43 # 4.0.0\n\n      - name: Bats tests\n        shell: bash\n        env:\n         BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}\n         TERM: xterm\n        run: |\n          bats -o _artifacts tests/\n\n      - name: Bats tests (custom network)\n        shell: bash\n        env:\n          BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}\n          TERM: xterm\n        run: |\n          bats -o _artifacts-custom-network tests/custom-network/\n\n      - name: Upload logs\n        if: always()\n        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5\n        with:\n          name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}\n          path: |\n            ./_artifacts\n            ./_artifacts-custom-network\n \n  bats_mac_tests:\n    runs-on: macos-15-intel\n    name: Bats e2e tests on Mac\n    # Skip until runner does not timeout on kind create cluster\n    if: false\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      # c.f. https://github.com/actions/runner-images/issues/13358\n      - name: Work around x86 macOS bug for multiple CPU cores\n        run: |\n          sudo defaults -currentHost write /Library/Preferences/com.apple.powerlogd SMCMonitorCadence 0\n          sudo killall PerfPowerServices || true\n      - name: Set up environment (download dependencies)\n        run: |\n          brew install docker colima\n          brew install kind\n          brew install golang\n          brew install bats-core\n          brew install kubectl\n          LIMA_SSH_PORT_FORWARDER=true colima start\n      - name: Bats tests\n        env:\n          TERM: linux\n        run: |\n          bash -c \"time bats -o _artifacts --trace --formatter tap tests/\"\n      - name: Debug info\n        if: always()\n        run: |\n          docker ps\n          kubectl get pods -v7\n          kubectl get services -v7\n\n      - name: Upload logs\n        if: always()\n        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5\n        with:\n          name: kind-logs-mac-${{ github.run_id }}\n          path: ./_artifacts\n"
  },
  {
    "path": ".github/workflows/gateway.yml",
    "content": "name: gateway\n\non:\n  push:\n  pull_request:\n  workflow_dispatch:\n\nenv:\n  GO_VERSION: \"1.25\"\n  GATEWAY_VERSION: \"v1.4.1\"\n  K8S_VERSION: \"v1.35.0\"\n  KIND_VERSION: \"v0.31.0\"\n  KIND_CLUSTER_NAME: \"kind-cloud\"\n\njobs:\n  gateway:\n    name: gateway\n    runs-on: ubuntu-latest\n    timeout-minutes: 100\n    env:\n      JOB_NAME: \"cloud-provider-kind-e2e-gateway\"\n    steps:\n    - name: Set up Go\n      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6\n      with:\n        go-version: ${{ env.GO_VERSION }}\n      id: go\n\n    - name: Check out code\n      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n\n    - name: Enable ipv4 and ipv6 forwarding\n      run: |\n        sudo sysctl -w net.ipv6.conf.all.forwarding=1\n        sudo sysctl -w net.ipv4.ip_forward=1\n\n    - name: Set up environment (download dependencies)\n      run: |\n        TMP_DIR=$(mktemp -d)\n        # Test binaries\n        git clone --branch ${{ env.GATEWAY_VERSION }} --depth 1 https://github.com/kubernetes-sigs/gateway-api.git ${TMP_DIR}\n        cd ${TMP_DIR}\n        go test ./conformance/ -c\n        cd -\n        sudo cp ${TMP_DIR}/conformance.test /usr/local/bin/conformance.test\n        sudo chmod +x /usr/local/bin/conformance.test\n        # kubectl\n        curl -L https://dl.k8s.io/${{ env.K8S_VERSION }}/bin/linux/amd64/kubectl -o ${TMP_DIR}/kubectl\n        # kind\n        curl -Lo ${TMP_DIR}/kind https://kind.sigs.k8s.io/dl/${{ env.KIND_VERSION }}/kind-linux-amd64\n        # Install\n        sudo cp ${TMP_DIR}/kubectl /usr/local/bin/kubectl\n        sudo cp ${TMP_DIR}/kind /usr/local/bin/kind\n        sudo chmod +x /usr/local/bin/kubectl\n        sudo chmod +x /usr/local/bin/kind\n        # Create folder to store artifacts\n        mkdir -p _artifacts\n\n    - name: Run cloud-provider-kind\n      run: |\n        make\n        nohup bin/cloud-provider-kind -v 2 --enable-log-dumping --logs-dir ./_artifacts/loadbalancers > ./_artifacts/ccm-kind.log 2>&1 &\n\n    - name: Create multi node cluster\n      run: |\n        # create cluster\n        cat <<EOF | /usr/local/bin/kind create cluster \\\n          --name ${{ env.KIND_CLUSTER_NAME}}           \\\n          --image kindest/node:${{ env.K8S_VERSION }}  \\\n          -v7 --wait 1m --retain --config=-\n        kind: Cluster\n        apiVersion: kind.x-k8s.io/v1alpha4\n        nodes:\n        - role: control-plane\n        - role: worker\n        - role: worker\n        kubeadmConfigPatches:\n          - |\n            kind: ClusterConfiguration\n            apiServer:\n              extraArgs:\n                v: \"5\"\n            controllerManager:\n              extraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n            ---\n            kind: InitConfiguration\n            nodeRegistration:\n              kubeletExtraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n            ---\n            kind: JoinConfiguration\n            nodeRegistration:\n              kubeletExtraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n        EOF\n        /usr/local/bin/kind get kubeconfig --name ${{ env.KIND_CLUSTER_NAME}} > _artifacts/kubeconfig.conf\n\n    - name: Get Cluster status\n      run: |\n        /usr/local/bin/kubectl get nodes -o yaml\n        /usr/local/bin/kubectl get pods -A -o wide\n        # wait network is ready\n        /usr/local/bin/kubectl wait --for=condition=ready pods --namespace=kube-system -l k8s-app=kube-dns --timeout=3m\n        /usr/local/bin/kubectl get nodes -o wide\n        /usr/local/bin/kubectl get pods -A\n\n    - name: Run tests\n      run: |\n        /usr/local/bin/conformance.test -test.run TestConformance \\\n            --debug=true \\\n            --kubeconfig=_artifacts/kubeconfig.conf \\\n            --organization=sigs.k8s.io \\\n            --project=cloud-provider-kind \\\n            --url=https://github.com/kubernetes-sigs/cloud-provider-kind \\\n            --version=${{ github.sha }} \\\n            --contact=https://github.com/kubernetes-sigs/cloud-provider-kind/issues/new \\\n            --gateway-class=cloud-provider-kind \\\n            --conformance-profiles=GATEWAY-HTTP \\\n            --supported-features=Gateway,HTTPRoute,ReferenceGrant \\\n            --report-output=./_artifacts/conformance.yaml\n\n    - name: Export logs\n      if: always()\n      run: |\n        /usr/local/bin/kind export logs --name ${{ env.KIND_CLUSTER_NAME}} ./_artifacts/logs\n        cp ./_artifacts/ccm-kind.log ./_artifacts/logs\n\n    - name: Upload logs\n      if: always()\n      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5\n      with:\n        name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}\n        path: ./_artifacts\n"
  },
  {
    "path": ".github/workflows/ingress.yml",
    "content": "name: ingress\n\non:\n  push:\n  pull_request:\n  workflow_dispatch:\n\nenv:\n  GO_VERSION: \"1.25\"\n  K8S_VERSION: \"v1.35.0\"\n  KIND_VERSION: \"v0.31.0\"\n  KIND_CLUSTER_NAME: \"kind-cloud\"\n\njobs:\n  ingress:\n    name: ingress\n    runs-on: ubuntu-latest\n    timeout-minutes: 100\n    env:\n      JOB_NAME: \"cloud-provider-kind-e2e-ingress\"\n    steps:\n    - name: Set up Go\n      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6\n      with:\n        go-version: ${{ env.GO_VERSION }}\n      id: go\n\n    - name: Check out code\n      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n\n    - name: Enable ipv4 and ipv6 forwarding\n      run: |\n        sudo sysctl -w net.ipv6.conf.all.forwarding=1\n        sudo sysctl -w net.ipv4.ip_forward=1\n\n    - name: Set up environment (download dependencies)\n      run: |\n        TMP_DIR=$(mktemp -d)\n        # kubectl\n        curl -L https://dl.k8s.io/${{ env.K8S_VERSION }}/bin/linux/amd64/kubectl -o ${TMP_DIR}/kubectl\n        # kind\n        curl -Lo ${TMP_DIR}/kind https://kind.sigs.k8s.io/dl/${{ env.KIND_VERSION }}/kind-linux-amd64\n        # Install\n        sudo cp ${TMP_DIR}/kubectl /usr/local/bin/kubectl\n        sudo cp ${TMP_DIR}/kind /usr/local/bin/kind\n        sudo chmod +x /usr/local/bin/kubectl\n        sudo chmod +x /usr/local/bin/kind\n        # Create folder to store artifacts\n        mkdir -p _artifacts\n\n    - name: Run cloud-provider-kind\n      run: |\n        make\n        nohup bin/cloud-provider-kind -v 2 --enable-log-dumping --logs-dir ./_artifacts/loadbalancers > ./_artifacts/ccm-kind.log 2>&1 &\n\n    - name: Create multi node cluster\n      run: |\n        # create cluster\n        cat <<EOF | /usr/local/bin/kind create cluster \\\n          --name ${{ env.KIND_CLUSTER_NAME}}           \\\n          --image kindest/node:${{ env.K8S_VERSION }}  \\\n          -v7 --wait 1m --retain --config=-\n        kind: Cluster\n        apiVersion: kind.x-k8s.io/v1alpha4\n        nodes:\n        - role: control-plane\n        - role: worker\n        - role: worker\n        kubeadmConfigPatches:\n          - |\n            kind: ClusterConfiguration\n            apiServer:\n              extraArgs:\n                v: \"5\"\n            controllerManager:\n              extraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n            ---\n            kind: InitConfiguration\n            nodeRegistration:\n              kubeletExtraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n            ---\n            kind: JoinConfiguration\n            nodeRegistration:\n              kubeletExtraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n        EOF\n        /usr/local/bin/kind get kubeconfig --name ${{ env.KIND_CLUSTER_NAME}} > _artifacts/kubeconfig.conf\n\n    - name: Get Cluster status\n      run: |\n        /usr/local/bin/kubectl get nodes -o yaml\n        /usr/local/bin/kubectl get pods -A -o wide\n        # wait network is ready\n        /usr/local/bin/kubectl wait --for=condition=ready pods --namespace=kube-system -l k8s-app=kube-dns --timeout=3m\n        /usr/local/bin/kubectl get nodes -o wide\n        /usr/local/bin/kubectl get pods -A\n\n    - name: Run tests\n      run: |\n        TMP_DIR=$(mktemp -d)\n        # Test binaries\n        git clone --depth 1 https://github.com/kubernetes-sigs/ingress-controller-conformance.git ${TMP_DIR}/ingress-controller-conformance\n        cd ${TMP_DIR}/ingress-controller-conformance\n        # Add the @skip tag to the incompatible test\n        # The Gateway spec for spec.hostnames: [\"*.foo.com\"] states it matches all subdomains.\n        # The Ingress spec for spec.rules.host: \"*.foo.com\" states it only matches a single subdomain level.\n        echo \"Skipping incompatible test: 'An Ingress with a wildcard host rule should not route traffic matching on more than a single dns label'\"\n        sed -i '/Scenario: An Ingress with a wildcard host rule should not route traffic matching on more than a single dns label/i @skip' features/host_rules.feature\n        echo \"Skipping load balancing spread test: 'An Ingress with no rules should send all requests to the default backend'\"\n        sed -i '/Scenario Outline: An Ingress with no rules should send all requests to the default backend/i @skip' features/load_balancing.feature\n        make build\n        chmod +x ingress-controller-conformance\n        ./ingress-controller-conformance           \\\n          --ingress-class=cloud-provider-kind      \\\n          --no-colors                              \\\n          --output-directory=\"${PWD}/_artifacts\"   \\\n          --tags=\"~@skip\"                          \\\n          --wait-time-for-ingress-status=65s\n\n    - name: Export logs\n      if: always()\n      run: |\n        /usr/local/bin/kind export logs --name ${{ env.KIND_CLUSTER_NAME}} ./_artifacts/logs\n        cp ./_artifacts/ccm-kind.log ./_artifacts/logs\n\n    - name: Upload logs\n      if: always()\n      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5\n      with:\n        name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}\n        path: ./_artifacts\n"
  },
  {
    "path": ".github/workflows/k8s.yml",
    "content": "name: k8s\n\non:\n  push:\n  pull_request:\n  workflow_dispatch:\n\nenv:\n  K8S_VERSION: \"v1.34.0\"\n  KIND_VERSION: \"v0.30.0\"\n  KIND_CLUSTER_NAME: \"kind-cloud\"\n\njobs:\n  k8s:\n    name: k8s\n    runs-on: ubuntu-latest\n    timeout-minutes: 100\n    strategy:\n      fail-fast: false\n      matrix:\n        # TODO add \"dual\", waiting on KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/3705-cloud-node-ips\n        ipFamily: [\"ipv4\", \"ipv6\"]\n    env:\n      JOB_NAME: \"cloud-provider-kind-e2e-${{ matrix.ipFamily }}\"\n      IP_FAMILY: ${{ matrix.ipFamily }}\n    steps:\n    - name: Set up Go\n      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0\n      with:\n        go-version: stable\n\n    - name: Check out code\n      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n\n    - name: Enable ipv4 and ipv6 forwarding\n      run: |\n        sudo sysctl -w net.ipv6.conf.all.forwarding=1\n        sudo sysctl -w net.ipv4.ip_forward=1\n\n    - name: Set up environment (download dependencies)\n      run: |\n        TMP_DIR=$(mktemp -d)\n        # Test binaries\n        curl -L https://dl.k8s.io/${{ env.K8S_VERSION }}/kubernetes-test-linux-amd64.tar.gz -o ${TMP_DIR}/kubernetes-test-linux-amd64.tar.gz\n        tar xvzf ${TMP_DIR}/kubernetes-test-linux-amd64.tar.gz \\\n          --directory ${TMP_DIR} \\\n          --strip-components=3 kubernetes/test/bin/ginkgo kubernetes/test/bin/e2e.test\n        # kubectl\n        curl -L https://dl.k8s.io/${{ env.K8S_VERSION }}/bin/linux/amd64/kubectl -o ${TMP_DIR}/kubectl\n        # kind\n        curl -Lo ${TMP_DIR}/kind https://kind.sigs.k8s.io/dl/${{ env.KIND_VERSION }}/kind-linux-amd64\n        # Install\n        sudo cp ${TMP_DIR}/ginkgo /usr/local/bin/ginkgo\n        sudo cp ${TMP_DIR}/e2e.test /usr/local/bin/e2e.test\n        sudo cp ${TMP_DIR}/kubectl /usr/local/bin/kubectl\n        sudo cp ${TMP_DIR}/kind /usr/local/bin/kind\n        sudo chmod +x /usr/local/bin/ginkgo\n        sudo chmod +x /usr/local/bin/e2e.test\n        sudo chmod +x /usr/local/bin/kubectl\n        sudo chmod +x /usr/local/bin/kind\n        # Create folder to store artifacts\n        mkdir -p _artifacts\n\n    - name: Run cloud-provider-kind\n      run: |\n        make\n        nohup bin/cloud-provider-kind -v 2 --enable-log-dumping --logs-dir ./_artifacts/loadbalancers > ./_artifacts/ccm-kind.log 2>&1 &\n\n    - name: Create multi node cluster\n      run: |\n        # create cluster\n        cat <<EOF | /usr/local/bin/kind create cluster \\\n          --name ${{ env.KIND_CLUSTER_NAME}}           \\\n          --image kindest/node:${{ env.K8S_VERSION }}  \\\n          -v7 --wait 1m --retain --config=-\n        kind: Cluster\n        apiVersion: kind.x-k8s.io/v1alpha4\n        networking:\n          ipFamily: ${IP_FAMILY}\n        nodes:\n        - role: control-plane\n        - role: worker\n        - role: worker\n        kubeadmConfigPatches:\n          - |\n            kind: ClusterConfiguration\n            apiServer:\n              extraArgs:\n                v: \"5\"\n            controllerManager:\n              extraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n            ---\n            kind: InitConfiguration\n            nodeRegistration:\n              kubeletExtraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n            ---\n            kind: JoinConfiguration\n            nodeRegistration:\n              kubeletExtraArgs:\n                cloud-provider: \"external\"\n                v: \"5\"\n        EOF\n        /usr/local/bin/kind get kubeconfig --name ${{ env.KIND_CLUSTER_NAME}} > _artifacts/kubeconfig.conf\n\n    - name: Workaround CoreDNS for IPv6 airgapped\n      if: ${{ matrix.ipFamily == 'ipv6' }}\n      run: |\n        # Patch CoreDNS to work in Github CI\n        # 1. Github CI doesn´t offer IPv6 connectivity, so CoreDNS should be configured\n        # to work in an offline environment:\n        # https://github.com/coredns/coredns/issues/2494#issuecomment-457215452\n        # 2. Github CI adds following domains to resolv.conf search field:\n        # .net.\n        # CoreDNS should handle those domains and answer with NXDOMAIN instead of SERVFAIL\n        # otherwise pods stops trying to resolve the domain.\n        # Get the current config\n        original_coredns=$(/usr/local/bin/kubectl get -oyaml -n=kube-system configmap/coredns)\n        echo \"Original CoreDNS config:\"\n        echo \"${original_coredns}\"\n        # Patch it\n        fixed_coredns=$(\n          printf '%s' \"${original_coredns}\" | sed \\\n            -e 's/^.*kubernetes cluster\\.local/& net/' \\\n            -e '/^.*upstream$/d' \\\n            -e '/^.*fallthrough.*$/d' \\\n            -e '/^.*forward . \\/etc\\/resolv.conf$/d' \\\n            -e '/^.*loop$/d' \\\n        )\n        echo \"Patched CoreDNS config:\"\n        echo \"${fixed_coredns}\"\n        printf '%s' \"${fixed_coredns}\" | /usr/local/bin/kubectl apply -f -\n\n    - name: Get Cluster status\n      run: |\n        /usr/local/bin/kubectl get nodes -o yaml\n        /usr/local/bin/kubectl get pods -A -o wide\n        # wait network is ready\n        /usr/local/bin/kubectl wait --for=condition=ready pods --namespace=kube-system -l k8s-app=kube-dns --timeout=3m\n        /usr/local/bin/kubectl get nodes -o wide\n        /usr/local/bin/kubectl get pods -A\n\n    - name: Run tests\n      run: |\n        export KUBERNETES_CONFORMANCE_TEST='y'\n        export E2E_REPORT_DIR=${PWD}/_artifacts\n\n        # Run tests and use aws (creates a null e2e provider) to not skip the loadbalancer tests\n        # \"should be able to create LoadBalancer Service without NodePort and change it\" : the LB implementation uses haproxy and NodePorts can not forward directly to the Pods\n        # \"should be able to change the type and ports of a TCP service\" : the test expects a connection refused haproxy seems to return EOF\n        # \"loadbalancer source ranges\" : fails on IPv6 only\n        /usr/local/bin/ginkgo --nodes=25                \\\n          --focus=\"sig-network\"     \\\n          --skip=\"Feature|Federation|PerformanceDNS|DualStack|Disruptive|Serial|KubeProxy|GCE|Netpol|NetworkPolicy|256.search.list.characters|LoadBalancer.Service.without.NodePort|type.and.ports.of.a.TCP.service|loadbalancer.source.ranges\"   \\\n          /usr/local/bin/e2e.test                       \\\n          --                                            \\\n          --kubeconfig=${PWD}/_artifacts/kubeconfig.conf     \\\n          --provider=aws                                \\\n          --dump-logs-on-failure=false                  \\\n          --report-dir=${E2E_REPORT_DIR}                \\\n          --disable-log-dump=true\n\n    - name: Upload Junit Reports\n      if: always()\n      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5\n      with:\n        name: kind-junit-${{ env.JOB_NAME }}-${{ github.run_id }}\n        path: './_artifacts/*.xml'\n\n    - name: Export logs\n      if: always()\n      run: |\n        /usr/local/bin/kind export logs --name ${{ env.KIND_CLUSTER_NAME}} ./_artifacts/logs\n        cp ./_artifacts/ccm-kind.log ./_artifacts/logs\n        cp ./_artifacts/loadbalancers/* ./_artifacts/logs\n\n    - name: Upload logs\n      if: always()\n      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5\n      with:\n        name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}\n        path: ./_artifacts/logs\n\n    - name: Publish Test Report\n      uses: mikepenz/action-junit-report@bccf2e31636835cf0874589931c4116687171386 # v6\n      if: always()\n      with:\n        report_paths: './_artifacts/*.xml'\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# .github/workflows/release.yml\nname: goreleaser\n\non:\n  push:\n    # run only against tags\n    tags:\n      - \"*\"\n\npermissions:\n  contents: write\n  packages: write\n  # issues: write\n\njobs:\n  goreleaser:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          fetch-depth: 0\n      - name: Set up Go\n        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0\n        with:\n          go-version: stable\n      - name: Run GoReleaser\n        uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0\n        with:\n          distribution: goreleaser\n          # 'latest', 'nightly', or a semver\n          version: latest\n          args: release --clean\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yaml",
    "content": "name: Test\n\non: [push, pull_request]\n\nenv:\n  REGISTRY: ghcr.io\n  IMAGE_NAME: sigs.k8s.io/cloud-provider-kind\n\npermissions: write-all\n\njobs:\n  test:\n    strategy:\n      fail-fast: false\n    runs-on: ubuntu-latest\n    steps:\n    - name: Set up Go\n      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0\n      with:\n        go-version: stable\n    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n    - run: make test\n    - run: make lint\n\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\nbin/\ndist/\n\n# macOS\n.DS_Store\n"
  },
  {
    "path": ".golangci.yaml",
    "content": "version: \"2\"\nrun:\n  tests: false\nlinters:\n  default: none\n  enable:\n    - errcheck\n    - gocritic\n    - govet\n    - ineffassign\n    - staticcheck\n  exclusions:\n    generated: lax\n    presets:\n      - comments\n      - common-false-positives\n      - legacy\n      - std-error-handling\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\nformatters:\n  exclusions:\n    generated: lax\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\n"
  },
  {
    "path": ".goreleaser.yaml",
    "content": "version: 2\nproject_name: cloud-provider-kind\nbuilds:\n  - env: [CGO_ENABLED=0]\n    goos:\n      - linux\n      - windows\n      - darwin\n    goarch:\n      - amd64\n      - arm64\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing Guidelines\n\nWelcome to Kubernetes. We are excited about the prospect of you joining our [community](https://git.k8s.io/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt:\n\n_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._\n\n## Getting Started\n\nWe have full documentation on how to get started contributing here:\n\n<!---\nIf your repo has certain guidelines for contribution, put them here ahead of the general k8s resources\n-->\n\n- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) - Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests\n- [Kubernetes Contributor Guide](https://k8s.dev/guide) - Main contributor documentation, or you can just jump directly to the [contributing page](https://k8s.dev/docs/guide/contributing/)\n- [Contributor Cheat Sheet](https://k8s.dev/cheatsheet) - Common resources for existing developers\n\n## Mentorship\n\n- [Mentoring Initiatives](https://k8s.dev/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!\n\n- [Slack channel](https://kubernetes.slack.com/messages/kind)\n- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-testing)\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM --platform=$BUILDPLATFORM golang:1.25\nWORKDIR /go/src\n# make deps fetching cacheable\nCOPY go.mod go.sum ./\nRUN go mod download\n# build\nCOPY . .\nARG TARGETARCH\nRUN GOARCH=$TARGETARCH make build\n\n# build real cloud-provider-kind image\nFROM docker:29-cli\nCOPY --from=0 --chown=root:root ./go/src/bin/cloud-provider-kind /bin/cloud-provider-kind\nENTRYPOINT [\"/bin/cloud-provider-kind\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Makefile",
    "content": "REPO_ROOT:=${CURDIR}\nOUT_DIR=$(REPO_ROOT)/bin\nKIND_CLOUD_BINARY_NAME?=cloud-provider-kind\n\n# go1.9+ can autodetect GOROOT, but if some other tool sets it ...\nGOROOT:=\n# enable modules\nGO111MODULE=on\n# disable CGO by default for static binaries\nCGO_ENABLED=0\nexport GOROOT GO111MODULE CGO_ENABLED\n\n\nbuild:\n\tgo build -v -o \"$(OUT_DIR)/$(KIND_CLOUD_BINARY_NAME)\" $(KIND_CLOUD_BUILD_FLAGS) main.go\n\nclean:\n\trm -rf \"$(OUT_DIR)/\"\n\ntest:\n\tCGO_ENABLED=1 go test -v -race -count 1 ./...\n\ne2e:\n\tcd tests && bats tests.bats\n\n# code linters\nlint:\n\thack/lint.sh\n\nupdate:\n\tgo mod tidy\n\n# get image name from directory we're building\nIMAGE_NAME?=cloud-provider-kind\n# docker image registry, default to upstream\nREGISTRY?=gcr.io/k8s-staging-kind\n# tag based on date-sha\nTAG?=$(shell echo \"$$(date +v%Y%m%d)-$$(git describe --always --dirty)\")\n# the full image tag\nCPK_IMAGE?=$(REGISTRY)/$(IMAGE_NAME):$(TAG)\nPLATFORMS?=linux/amd64,linux/arm64\n\n.PHONY: ensure-buildx\nensure-buildx:\n\t./hack/init-buildx.sh\n\nimage-build:\n\tdocker buildx build . \\\n\t\t--tag=\"${CPK_IMAGE}\" \\\n\t\t--load\n\nimage-push:\n\tdocker buildx build . \\\n\t\t--platform=\"${PLATFORMS}\" \\\n\t\t--tag=\"${CPK_IMAGE}\" \\\n\t\t--push\n\n.PHONY: release # Build a multi-arch docker image\nrelease: ensure-buildx image-push\n"
  },
  {
    "path": "OWNERS",
    "content": "# See the OWNERS docs at https://go.k8s.io/owners\n\napprovers:\n  - aojea\n  - bentheelder\n  - stmcginnis\n"
  },
  {
    "path": "README.md",
    "content": "# Kubernetes Cloud Provider for KIND\n\nKIND has demonstrated to be a very versatile, efficient, cheap and very useful tool for Kubernetes testing. However, KIND doesn't offer capabilities for testing all the features that depend on cloud-providers, specifically the Load Balancers, causing a gap on testing and a bad user experience, since is not easy to connect to the applications running on the cluster.\n\n`cloud-provider-kind` aims to fill this gap and provide an agnostic and cheap solution for all the Kubernetes features that depend on a cloud-provider using KIND.\n\n- [Slack channel](https://kubernetes.slack.com/messages/kind)\n- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-testing)\n\n## Talks\n\nKubecon EU 2024 - [Keep Calm and Load Balance on KIND - Antonio Ojea & Benjamin Elder, Google](https://sched.co/1YhhY)\n\n[![Keep Calm and Load Balance on KIND](https://img.youtube.com/vi/U6_-y24rJnI/0.jpg)](https://www.youtube.com/watch?v=U6_-y24rJnI)\n\n## Install\n\n### Installing with `go install`\n\nYou can install `cloud-provider-kind` using `go install`:\n\n```sh\ngo install sigs.k8s.io/cloud-provider-kind@latest\n```\n\nThis will install the binary in `$GOBIN` (typically `~/go/bin`); you\ncan make it available elsewhere if appropriate:\n\n```sh\nsudo install ~/go/bin/cloud-provider-kind /usr/local/bin\n```\n\n### Installing With A Package Manager\n\nThe cloud-provider-kind community has enabled installation via the following package managers.\n\n> [!NOTE]\n> The following are community supported efforts. The `cloud-provider-kind` maintainers are not involved in the creation of these packages, and the upstream community makes no claims on the validity, safety, or content of them.\n\nOn macOS via Homebrew:\n\n```sh\nbrew install cloud-provider-kind\n```\n\n### Running via Docker Image\n\nStarting with v0.4.0, the docker image for cloud-provider-kind is available\nat `registry.k8s.io/cloud-provider-kind/cloud-controller-manager`\n\nYou can also build it locally:\n\n```sh\ngit clone https://github.com/kubernetes-sigs/cloud-provider-kind.git\nCloning into 'cloud-provider-kind'...\nremote: Enumerating objects: 6779, done.\nremote: Counting objects: 100% (6779/6779), done.\nremote: Compressing objects: 100% (4225/4225), done.q\nremote: Total 6779 (delta 2150), reused 6755 (delta 2135), pack-reused 0\nReceiving objects: 100% (6779/6779), 9.05 MiB | 1.83 MiB/s, done.\nResolving deltas: 100% (2150/2150), done.\n\ncd cloud-provider-kind && make\nsudo mv ./bin/cloud-provider-kind  /usr/local/bin/cloud-provider-kind\n```\n\nAnother alternative is to run it as a container, but this will require to mount\nthe docker socket inside the container:\n\n```sh\ndocker build . -t cloud-provider-kind\n# using the host network\ndocker run --rm --network host -v /var/run/docker.sock:/var/run/docker.sock cloud-provider-kind\n# or the kind network\ndocker run --rm --network kind -v /var/run/docker.sock:/var/run/docker.sock cloud-provider-kind\n```\n\nOr using `compose.yaml` file:\n\n```sh\n# using the `kind` network (`host` is the default value for NET_MODE)\nNET_MODE=kind docker compose up -d\n```\n\n## Gateway API support\n\nThis provider has support for the [Gateway API](https://gateway-api.sigs.k8s.io/).\nIt implements the `Gateway` and `HTTPRoute` functionalities and passes the community conformance tests.\n\nThe Gateway API controller is enabled by default using the standard channel,\nbut you can select the Gateway API release channel (standard/experimental) or just disable the feature completely\nusing the flag `gateway-channel`:\n\n```sh\ncloud-provider-kind --gateway-channel standard|experimental|disabled\n```\n\n## How to use it\n\nRun a KIND cluster:\n\n```sh\n$ kind create cluster\nCreating cluster \"kind\" ...\n ✓ Ensuring node image (kindest/node:v1.26.0) 🖼\n ✓ Preparing nodes 📦\n ✓ Writing configuration 📜\n ✓ Starting control-plane 🕹️\n ✓ Installing CNI 🔌\n ✓ Installing StorageClass 💾\nSet kubectl context to \"kind-kind\"\nYou can now use your cluster with:\n\nkubectl cluster-info --context kind-kind\n\nHave a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂\n\n```\n\n### Allowing load balancers access to control plane nodes\n\nBy default, [Kubernetes expects workloads will not run on control plane nodes](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#control-plane-node-isolation)\nand labels them with [`node.kubernetes.io/exclude-from-external-load-balancers`](https://kubernetes.io/docs/reference/labels-annotations-taints/#node-kubernetes-io-exclude-from-external-load-balancers),\nwhich stops load balancers from accessing them.\n\nIf you are running workloads on control plane nodes, as is the [default kind configuration](https://kind.sigs.k8s.io/docs/user/configuration/#nodes),\nyou will need to remove this label to access them using a LoadBalancer:\n\n```sh\n$ kubectl label node kind-control-plane node.kubernetes.io/exclude-from-external-load-balancers-\n```\n\n### Running the provider\n\nOnce the cluster is running, we need to run the `cloud-provider-kind` in a terminal and keep it running. The `cloud-provider-kind` will monitor all your KIND clusters and `Services` with Type `LoadBalancer` and create the corresponding LoadBalancer containers that will expose those Services.\n\n```sh\nbin/cloud-provider-kind\nI0416 19:58:18.391222 2526219 controller.go:98] Creating new cloud provider for cluster kind\nI0416 19:58:18.398569 2526219 controller.go:105] Starting service controller for cluster kind\nI0416 19:58:18.399421 2526219 controller.go:227] Starting service controller\nI0416 19:58:18.399582 2526219 shared_informer.go:273] Waiting for caches to sync for service\nI0416 19:58:18.500460 2526219 shared_informer.go:280] Caches are synced for service\n...\n```\n\n### Configuring Proxy Image Registry\n\n> [!WARNING]\n> The proxy image is an implementation detail of `cloud-provider-kind` and it is not guaranteed to be stable.\n> Changing the image version or tag is not supported and may break the cloud provider.\n> Use the following instructions only for mirroring the image to a private registry.\n\nYou can check the image used by the current version of `cloud-provider-kind` running:\n\n```sh\nbin/cloud-provider-kind list-images\n```\n\nIf you need to mirror the image to a private registry, you can override the registry URL using the `CLOUD_PROVIDER_KIND_REGISTRY_URL` environment variable.\nThis will use the same image name and tag but with the specified registry.\n\nExample of use mirror registry:\n\n```sh\nCLOUD_PROVIDER_KIND_REGISTRY_URL=\"<your-mirror-registry-url>\" bin/cloud-provider-kind\n```\n\n### Creating a Service and exposing it via a LoadBalancer\n\nLet's create an application that listens on port 8080 and expose it in the port 80 using a LoadBalancer.\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: policy-local\n  labels:\n    app: MyLocalApp\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: MyLocalApp\n  template:\n    metadata:\n      labels:\n        app: MyLocalApp\n    spec:\n      containers:\n        - name: agnhost\n          image: registry.k8s.io/e2e-test-images/agnhost:2.40\n          args:\n            - netexec\n            - --http-port=8080\n            - --udp-port=8080\n          ports:\n            - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: lb-service-local\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: MyLocalApp\n  ports:\n    - protocol: TCP\n      port: 80\n      targetPort: 8080\n```\n\n```sh\n$ kubectl apply -f examples/loadbalancer_etp_local.yaml\ndeployment.apps/policy-local created\nservice/lb-service-local created\n$ kubectl get service/lb-service-local\nNAME               TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\nlb-service-local   LoadBalancer   10.96.207.137   192.168.8.7   80:31215/TCP   57s\n```\n\nWe can see how the `EXTERNAL-IP` field contains an IP, and we can use it to connect to our\napplication.\n\n```\n$ curl  192.168.8.7:80/hostname\npolicy-local-59854877c9-xwtfk\n\n$  kubectl get pods\nNAME                            READY   STATUS    RESTARTS   AGE\npolicy-local-59854877c9-xwtfk   1/1     Running   0          2m38s\n```\n\n### Creating a Gateway and a HTTPRoute\n\nSimilar to Services with LoadBalancers we can use Gateway API\n\n```yaml\napiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n  name: prod-web\nspec:\n  gatewayClassName: cloud-provider-kind\n  listeners:\n  - protocol: HTTP\n    port: 80\n    name: prod-web-gw\n    allowedRoutes:\n      namespaces:\n        from: Same\n---\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: foo\nspec:\n  parentRefs:\n  - name: prod-web\n  rules:\n  - backendRefs:\n    - name: myapp-svc\n      port: 8080\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: myapp\nspec:\n  selector:\n    matchLabels:\n      app: MyApp\n  replicas: 1\n  template:\n    metadata:\n      labels:\n        app: MyApp\n    spec:\n      containers:\n      - name: myapp\n        image: registry.k8s.io/e2e-test-images/agnhost:2.39\n        args:\n          - netexec\n          - --http-port=80\n          - --delay-shutdown=30\n        ports:\n          - name: httpd\n            containerPort: 80\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: myapp-svc\nspec:\n  type: ClusterIP\n  selector:\n    app: MyApp\n  ports:\n    - name: httpd\n      port: 8080\n      targetPort: 80\n```\n\nWe can get the external IP associated to the gateway:\n\n```sh\n kubectl get gateway\nNAME       CLASS                 ADDRESS       PROGRAMMED   AGE\nprod-web   cloud-provider-kind   192.168.8.5   True         3d21h\n```\n\nand the HTTPRoutes\n\n```sh\nkubectl get httproutes\nNAME   HOSTNAMES   AGE\nfoo                3d21h\n```\n\nand test that works:\n\n```sh\n$ curl 192.168.8.5/hostname\nmyapp-7dcffbf547-9kl2d\n```\n\n### Enabling Load Balancer Port Mapping\n\nWhen running `cloud-provider-kind` in a container on Windows or macOS, accessing\n`LoadBalancer` services can be challenging. Similar problems occur when running\nPodman as root, since Podman does not allow binding to privileged ports (e.g.,\n1-1024). The `--enable-lb-port-mapping` flag provides a solution by enabling the\nnecessary port mapping, allowing host access to these services. It is\nautomatically enabled on platforms where this is required. See [Mac, Windows and\nWSL2 support](#mac-windows-and-wsl2-support) section for more details.\n\nTo connect to your service in these cases, run `cloud-provider-kind` with the\n`--enable-lb-port-mapping` option. This configures the Envoy container with an\nephemeral host port that maps to the port the `LoadBalancer`'s external IP is\nlistening on.\n\n```sh\nbin/cloud-provider-kind --enable-lb-port-mapping\n```\n\nFor example, given a `LoadBalancer` listening on port `5678`.\n\n```sh\n> kubectl get service\nNAME          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE\nfoo-service   LoadBalancer   10.96.240.105   10.89.0.10    5678:31889/TCP   14m\n```\n\nThe Envoy container will have an ephemeral port (e.g., `42381`) mapped to the\n`LoadBalancer`'s port `5678`.\n\n```sh\n> podman ps\nCONTAINER ID  IMAGE                                                                                           COMMAND               CREATED         STATUS         PORTS                                              NAMES\nd261abc4b540  docker.io/envoyproxy/envoy:v1.30.1                                                              bash -c echo -en ...  21 seconds ago  Up 22 seconds  0.0.0.0:42381->5678/tcp, 0.0.0.0:36673->10000/tcp  kindccm-TLRDKPBWWH4DUSI7J7BNE3ABETEPCKSYA6UIWR5B\n```\n\nUse this ephemeral port to connect to the service.\n\n```sh\ncurl localhost:42381\n```\n\n### Mac, Windows and WSL2 support\n\nMac and Windows run the containers inside a VM and, on the contrary to Linux, the KIND nodes are not reachable from the host,\nso the LoadBalancer assigned IP is not working for users.\n\nTo solve this problem, cloud-provider-kind, leverages the existing docker portmap capabilities to expose the Loadbalancer IP and Ports\non the host. When you start cloud-provider-kind and create a LoadBalancer service, you will notice that a container named `kindccm-...` is launched within Docker. You can access the service by using the port exposed from the container to the host machine with `localhost`.\n\nFor WSL2, it is recommended to use the default [NAT](https://learn.microsoft.com/en-us/windows/wsl/networking) network mode with Docker Desktop on Windows. On WSL2, you can access the service via the external IP. On Windows, you can access the service by leveraging Docker's portmap capabilities.\n\nLimitations:\n\n- Mutation of Services, adding or removing ports to an existing Services, is not supported.\n- cloud-provider-kind binary needs permissions to add IP address to interfaces and to listen on privileged ports.\n- Overlapping IP between the containers and the host can break connectivity.\n\nMainly tested with `docker` and `Linux`, though `Windows`, `Mac` and `WSL2` are also basically supported:\n\n- On macOS and WSL2 you must run cloud-provider-kind using `sudo`\n- On Windows you must run cloud-provider-kind from a shell that uses `Run as administrator`\n- Further feedback from users will be helpful to support other related platforms.\n\n**Note**\n\nThe project is still in very alpha state, bugs are expected, please report them back opening a Github issue.\n\n### Code of conduct\n\nParticipation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).\n\n[owners]: https://git.k8s.io/community/contributors/guide/owners.md\n[Creative Commons 4.0]: https://git.k8s.io/website/LICENSE\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Security Announcements\n\nJoin the [kubernetes-security-announce] group for security and vulnerability announcements.\n\n## Reporting a Vulnerability\n\nInstructions for reporting a vulnerability can be found on the\n[Kubernetes Security and Disclosure Information] page.\n\n## Supported Versions\n\nInformation about supported Kubernetes versions can be found on the\n[Kubernetes version and version skew support policy] page on the Kubernetes website.\n\n[kubernetes-security-announce]: https://groups.google.com/forum/#!forum/kubernetes-security-announce\n[Kubernetes version and version skew support policy]: https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions\n[Kubernetes Security and Disclosure Information]: https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability\n"
  },
  {
    "path": "SECURITY_CONTACTS",
    "content": "# Defined below are the security contacts for this repo.\n#\n# They are the contact point for the Security Response Committee to reach out\n# to for triaging and handling of incoming issues.\n#\n# The below names agree to abide by the\n# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)\n# and will be removed and replaced if they violate that agreement.\n#\n# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE\n# INSTRUCTIONS AT https://kubernetes.io/security/\n\naojea\nbentheelder\n"
  },
  {
    "path": "cloudbuild.yaml",
    "content": "# See https://cloud.google.com/cloud-build/docs/build-config\noptions:\n  substitution_option: ALLOW_LOOSE\n  machineType: E2_HIGHCPU_32\nsteps:\n- name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20240718-5ef92b5c36\n  entrypoint: make\n  env:\n  - REGISTRY=us-central1-docker.pkg.dev/k8s-staging-images/cloud-provider-kind\n  - IMAGE_NAME=cloud-controller-manager\n  args: ['release']\n"
  },
  {
    "path": "cmd/app.go",
    "content": "package cmd\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/component-base/logs\"\n\t\"k8s.io/klog/v2\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/controller\"\n\t\"sigs.k8s.io/kind/pkg/cluster\"\n\tkindcmd \"sigs.k8s.io/kind/pkg/cmd\"\n)\n\nvar (\n\tflagV                int\n\tenableLogDump        bool\n\tlogDumpDir           string\n\tenableLBPortMapping  bool\n\tgatewayChannel       string\n\tenableDefaultIngress bool\n)\n\nfunc Main() {\n\tcmd := NewCommand()\n\tif err := cmd.Execute(); err != nil {\n\t\tos.Exit(1)\n\t}\n}\n\nfunc NewCommand() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"cloud-provider-kind\",\n\t\tShort: \"cloud-provider-kind is a cloud provider for kind clusters\",\n\t\tRunE:  runE,\n\t\t// We silence usage on error because we don't want to print usage\n\t\t// when the command fails due to a runtime error.\n\t\tSilenceUsage: true,\n\t}\n\n\t// Register flags\n\tcmd.Flags().IntVarP(&flagV, \"verbosity\", \"v\", 2, \"Verbosity level\")\n\tcmd.Flags().BoolVar(&enableLogDump, \"enable-log-dumping\", false, \"store logs to a temporal directory or to the directory specified using the logs-dir flag\")\n\tcmd.Flags().StringVar(&logDumpDir, \"logs-dir\", \"\", \"store logs to the specified directory\")\n\tcmd.Flags().BoolVar(&enableLBPortMapping, \"enable-lb-port-mapping\", false, \"enable port-mapping on the load balancer ports\")\n\tcmd.Flags().StringVar(&gatewayChannel, \"gateway-channel\", \"standard\", \"define the gateway API release channel to be used (standard, experimental, disabled), by default is standard\")\n\tcmd.Flags().BoolVar(&enableDefaultIngress, \"enable-default-ingress\", true, \"enable default ingress for the cloud provider kind ingress\")\n\n\n\tcmd.AddCommand(newListImagesCommand())\n\n\treturn cmd\n}\n\nfunc newListImagesCommand() *cobra.Command {\n\treturn &cobra.Command{\n\t\tUse:   \"list-images\",\n\t\tShort: \"list images used by cloud-provider-kind\",\n\t\tRun: func(cmd *cobra.Command, args []string) {\n\t\t\tfmt.Println(config.DefaultConfig.ProxyImage)\n\t\t},\n\t}\n}\n\nfunc runE(cmd *cobra.Command, args []string) error {\n\t// Log flags\n\tcmd.Flags().VisitAll(func(flag *pflag.Flag) {\n\t\tklog.Infof(\"FLAG: --%s=%q\", flag.Name, flag.Value)\n\t})\n\n\t// Process on macOS must run using sudo\n\tif runtime.GOOS == \"darwin\" && syscall.Geteuid() != 0 {\n\t\treturn fmt.Errorf(\"please run this again with `sudo`\")\n\t}\n\n\t// trap Ctrl+C and call cancel on the context\n\tctx := context.Background()\n\tctx, cancel := context.WithCancel(ctx)\n\n\t// Enable signal handler\n\tsignalCh := make(chan os.Signal, 2)\n\tdefer func() {\n\t\tclose(signalCh)\n\t\tcancel()\n\t}()\n\n\tsignal.Notify(signalCh, syscall.SIGTERM, syscall.SIGINT)\n\tgo func() {\n\t\tselect {\n\t\tcase <-signalCh:\n\t\t\tklog.Infof(\"Exiting: received signal\")\n\t\t\tcancel()\n\t\tcase <-ctx.Done():\n\t\t\t// cleanup\n\t\t}\n\t}()\n\n\t// initialize loggers, kind logger and klog\n\tlogger := kindcmd.NewLogger()\n\ttype verboser interface {\n\t\tSetVerbosity(int)\n\t}\n\tv, ok := logger.(verboser)\n\tif ok {\n\t\tv.SetVerbosity(flagV)\n\t}\n\n\t_, err := logs.GlogSetter(strconv.Itoa(flagV))\n\tif err != nil {\n\t\tlogger.Errorf(\"error setting klog verbosity to %d : %v\", flagV, err)\n\t}\n\n\tconfig.DefaultConfig.IngressDefault = enableDefaultIngress\n\n\t// Validate gateway channel\n\tchannel := config.GatewayReleaseChannel(gatewayChannel)\n\tif channel != config.Standard && channel != config.Experimental && channel != config.Disabled {\n\t\treturn fmt.Errorf(\"unknown Gateway API release channel %q\", gatewayChannel)\n\t}\n\tconfig.DefaultConfig.GatewayReleaseChannel = channel\n\n\t// initialize log directory\n\tif enableLogDump {\n\t\tif logDumpDir == \"\" {\n\t\t\tdir, err := os.MkdirTemp(os.TempDir(), \"kind-provider-\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tlogDumpDir = dir\n\t\t}\n\n\t\tif _, err := os.Stat(logDumpDir); os.IsNotExist(err) {\n\t\t\tif err := os.MkdirAll(logDumpDir, 0755); err != nil {\n\t\t\t\treturn fmt.Errorf(\"directory %s does not exist: %v\", logDumpDir, err)\n\t\t\t}\n\t\t}\n\t\tconfig.DefaultConfig.EnableLogDump = true\n\t\tconfig.DefaultConfig.LogDir = logDumpDir\n\t\tklog.Infof(\"**** Dumping load balancers logs to: %s\", logDumpDir)\n\t}\n\n\t// some platforms require to enable tunneling for the LoadBalancers\n\tif runtime.GOOS == \"darwin\" || runtime.GOOS == \"windows\" || isWSL2() {\n\t\tconfig.DefaultConfig.LoadBalancerConnectivity = config.Tunnel\n\t}\n\n\t// flag overrides autodetection\n\tif enableLBPortMapping {\n\t\tconfig.DefaultConfig.LoadBalancerConnectivity = config.Portmap\n\t}\n\n\t// default control plane connectivity to portmap, it will be\n\t// overriden if the first cluster added detects direct\n\t// connecitivity\n\tconfig.DefaultConfig.ControlPlaneConnectivity = config.Portmap\n\n\t// initialize kind provider\n\tvar option cluster.ProviderOption\n\tswitch p := container.Runtime(); p {\n\tcase \"podman\":\n\t\toption = cluster.ProviderWithPodman()\n\tcase \"nerdctl\", \"finch\", \"nerdctl.lima\":\n\t\toption = cluster.ProviderWithNerdctl(p)\n\tdefault:\n\t\toption = cluster.ProviderWithDocker()\n\t}\n\tkindProvider := cluster.NewProvider(\n\t\toption,\n\t\tcluster.ProviderWithLogger(logger),\n\t)\n\tcontroller.New(kindProvider).Run(ctx)\n\treturn nil\n}\n\nfunc isWSL2() bool {\n\tif v, err := os.ReadFile(\"/proc/version\"); err == nil {\n\t\treturn strings.Contains(string(v), \"WSL2\")\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "code-of-conduct.md",
    "content": "# Kubernetes Community Code of Conduct\n\nPlease refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)\n"
  },
  {
    "path": "compose.yml",
    "content": "services:\n  cloud-provider:\n    build: .\n    network_mode: \"${NET_MODE-host}\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n"
  },
  {
    "path": "docs/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/HOWTO.md",
    "content": "# Documentation Guide\n\nThis documentation site is generated and served using **Docsify**, a lightweight documentation site generator that renders Markdown files on the fly.\n\n## Serving the Docsify Site\n\nTo run the documentation locally:\n\n```bash\ndocsify serve ./docs\n```\n\nThis command starts a local server and serves the documentation from the current directory.\nOpen the provided URL in your browser to view the site.\n\n---\n\n## Adding a New Link to the Sidebar\n\nThe sidebar content is managed by the `_sidebar.md` file.\nTo add a new link:\n\n1. Open `_sidebar.md`\n2. Insert a new list item pointing to your Markdown file, for example:\n\n```markdown\n- [Install Docker](user/install/install_docker.md)\n- [Gateway API Overview](user/gateway/gatewayapi.md)\n```\n\nDocsify will automatically load the linked page when clicked.\n\n---\n\n## Adding a New Page\n\nTo create a new documentation page:\n\n1. Add a new `.md` file under the appropriate folder.\n   Example:\n\n```\nuser/example/new_feature_guide.md\n```\n\n2. Add a link to this file in `_sidebar.md` so it appears in navigation.\n\n---\n\n## Folder Structure Overview\n\nBelow is the current folder hierarchy used for organizing the docs:\n\n```\n├── code-of-conduct.md               # Code of Conduct guidelines\n├── contributing/\n│   └── CONTRIBUTING.md              # Contribution guide\n├── _coverpage.md                    # Docsify cover page configuration\n├── design/\n│   └── images                       # Design-related assets\n├── HOWTO.md                         # General how-to guide\n├── index.html                       # Docsify entry point\n├── README.md                        # Project introduction\n├── _sidebar.md                      # Sidebar navigation config\n└── user/\n    ├── example/                     # Example implementation guides\n    ├── gateway/                     # Gateway-related configuration guides\n    ├── howto.md                     # Additional user how-tos\n    ├── images/                      # Image assets for user docs\n    ├── ingress/                     # Ingress-related guides\n    ├── install/                     # Installation instructions\n    ├── os_support.md                # OS support documentation\n    └── support/                     # Support-related docs\n```\n\nThis structure helps keep the content organized by feature areas and documentation types.\n\n---\n\n## Further Configuration\n\nFor more advanced configuration, theming, plugins, and deployment options, please refer to the official Docsify documentation:\n\n[https://docsify.js.org](https://docsify.js.org)\n\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Kubernetes Cloud Provider for KIND\n\nKIND has demonstrated to be a very versatile, efficient, cheap and very useful tool for Kubernetes testing. However, KIND doesn't offer capabilities for testing all the features that depend on cloud-providers, specifically the Load Balancers, causing a gap on testing and a bad user experience, since is not easy to connect to the applications running on the cluster.\n\n`cloud-provider-kind` aims to fill this gap and provide an agnostic and cheap solution for all the Kubernetes features that depend on a cloud-provider using KIND.\n\n- [Slack channel](https://kubernetes.slack.com/messages/kind)\n- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-testing)\n\n## Talks\n\nKubecon EU 2024 - [Keep Calm and Load Balance on KIND - Antonio Ojea & Benjamin Elder, Google](https://sched.co/1YhhY)\n\n[![Keep Calm and Load Balance on KIND](https://img.youtube.com/vi/U6_-y24rJnI/0.jpg)](https://www.youtube.com/watch?v=U6_-y24rJnI)\n\n\n\n### Code of conduct\n\nParticipation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).\n\n[owners]: https://git.k8s.io/community/contributors/guide/owners.md\n[Creative Commons 2.0]: https://git.k8s.io/website/LICENSE\n"
  },
  {
    "path": "docs/_coverpage.md",
    "content": "# Kubernetes Cloud Provider for KIND <small></small>\n\n> cloud-provider-kind aims to fill this gap and provide an agnostic and cheap solution for all the Kubernetes features that depend on a cloud-provider using KIND.\n\n\n[GitHub](//github.com/kubernetes-sigs/cloud-provider-kind)\n[Get Started](#main)"
  },
  {
    "path": "docs/_sidebar.md",
    "content": "- Install \n\n  - [Installation with go ](user/install/install_go.md)\n  - [Running with docker](user/install/install_docker.md)\n- Ingress\n  - [Setting up Ingress](user/ingress/ingress.md)\n- Gateway API \n  - [Gateway API Support (Alpha)](user/gateway/gatewayapi.md)\n  - [LoadBalancer Access to ControlPlane](user/gateway/allow_load_balancer_access_control_plane.md)\n  - [Running the Provider](user/gateway/running_the_provider.md)\n  - [Configuring Proxy Image Registry](user/gateway/configure_proxy_image_registry.md)\n\n- Usage Examples\n  - [Creating service via a LoadBalancer](user/example/service_expose_via_loadbalancer.md)\n  - [Creating a Gateway and a HTTPRoute](user/example/creating_gateway_http_route.md.md)\n  - [Enabling Load Balancer Port Mapping](user/example/enable_lb_port_mapping.md)\n\n- Support\n  - [Mac, Windows and WSL2 support](user/support/os_support.md)\n\n- Contributing\n  - [Contribution Guide Lines](contributing/CONTRIBUTING.md)\n"
  },
  {
    "path": "docs/code-of-conduct.md",
    "content": "# Kubernetes Community Code of Conduct\n\nPlease refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)\n"
  },
  {
    "path": "docs/contributing/CONTRIBUTING.md",
    "content": "# Contributing Guidelines\n\nWelcome to Kubernetes. We are excited about the prospect of you joining our [community](https://git.k8s.io/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt:\n\n_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._\n\n## Getting Started\n\nWe have full documentation on how to get started contributing here:\n\n<!---\nIf your repo has certain guidelines for contribution, put them here ahead of the general k8s resources\n-->\n\n- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) - Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests\n- [Kubernetes Contributor Guide](https://k8s.dev/guide) - Main contributor documentation, or you can just jump directly to the [contributing page](https://k8s.dev/docs/guide/contributing/)\n- [Contributor Cheat Sheet](https://k8s.dev/cheatsheet) - Common resources for existing developers\n\n## Mentorship\n\n- [Mentoring Initiatives](https://k8s.dev/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!\n\n- [Slack channel](https://kubernetes.slack.com/messages/kind)\n- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-testing)\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Kubernetes Cloud Provider for KIND</title>\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n  <meta name=\"description\" content=\"cloud-provider-kind` aims to fill this gap and provide an agnostic and cheap solution for all the Kubernetes features that depend on a cloud-provider using KIND.\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, minimum-scale=1.0\">\n\n\n  <link rel=\"stylesheet\" href=\"//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css\">\n  <link \n    rel=\"stylesheet\"\n    href=\"//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css\"\n    title=\"docsify-darklight-theme\"\n    type=\"text/css\"\n/>\n</head>\n<body>\n  <div id=\"app\"></div>\n  <script>\n    window.$docsify = {\n      name: 'Kubernetes Cloud Provider for KIND',\n      \n      repo: 'https://github.com/kubernetes-sigs/cloud-provider-kind',\n      loadSidebar:true,\n      auto2top: true,\n      coverpage: true,\n      search: 'auto',\n        darklightTheme: {\n          defaultTheme : 'light',\n        }\n      // autoHeader: true,\n    }\n  </script>\n  <!-- Docsify v4 -->\n  <script src=\"//cdn.jsdelivr.net/npm/docsify@4\"></script>\n  <script src=\"//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js\"></script>\n  <script src=\"//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js\"></script>\n  <script src=\"//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js\"></script>\n  <script src=\"//cdn.jsdelivr.net/npm/prismjs@1/components/prism-yaml.min.js\"></script>\n\n  <script \n    src=\"//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js\"\n    type=\"text/javascript\">\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/user/example/creating_gateway_http_route.md",
    "content": "### Creating a Gateway and a HTTPRoute\n\nSimilar to Services with LoadBalancers we can use Gateway API\n\n```yaml\napiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n  name: prod-web\nspec:\n  gatewayClassName: cloud-provider-kind\n  listeners:\n  - protocol: HTTP\n    port: 80\n    name: prod-web-gw\n    allowedRoutes:\n      namespaces:\n        from: Same\n---\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: foo\nspec:\n  parentRefs:\n  - name: prod-web\n  rules:\n  - backendRefs:\n    - name: myapp-svc\n      port: 8080\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: myapp\nspec:\n  selector:\n    matchLabels:\n      app: MyApp\n  replicas: 1\n  template:\n    metadata:\n      labels:\n        app: MyApp\n    spec:\n      containers:\n      - name: myapp\n        image: registry.k8s.io/e2e-test-images/agnhost:2.39\n        args:\n          - netexec\n          - --http-port=80\n          - --delay-shutdown=30\n        ports:\n          - name: httpd\n            containerPort: 80\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: myapp-svc\nspec:\n  type: ClusterIP\n  selector:\n    app: MyApp\n  ports:\n    - name: httpd\n      port: 8080\n      targetPort: 80\n```\n\nWe can get the external IP associated to the gateway:\n\n```sh\n kubectl get gateway\nNAME       CLASS                 ADDRESS       PROGRAMMED   AGE\nprod-web   cloud-provider-kind   192.168.8.5   True         3d21h\n```\n\nand the HTTPRoutes\n\n```sh\nkubectl get httproutes\nNAME   HOSTNAMES   AGE\nfoo                3d21h\n```\n\nand test that works:\n\n```sh\n$ curl 192.168.8.5/hostname\nmyapp-7dcffbf547-9kl2d\n```\n"
  },
  {
    "path": "docs/user/example/enable_lb_port_mapping.md",
    "content": "### Enabling Load Balancer Port Mapping\n\nWhen running `cloud-provider-kind` in a container on Windows or macOS, accessing\n`LoadBalancer` services can be challenging. Similar problems occur when running\nPodman as root, since Podman does not allow binding to privileged ports (e.g.,\n1-1024). The `-enable-lb-port-mapping` flag provides a solution by enabling the\nnecessary port mapping, allowing host access to these services.\n\nTo connect to your service in these cases, run `cloud-provider-kind` with the\n`-enable-lb-port-mapping` option. This configures the Envoy container with an\nephemeral host port that maps to the port the `LoadBalancer`'s external IP is\nlistening on.\n\n```\nbin/cloud-provider-kind -enable-lb-port-mapping\n```\n\nFor example, given a `LoadBalancer` listening on port `5678`.\n\n```\n> kubectl get service\nNAME          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE\nfoo-service   LoadBalancer   10.96.240.105   10.89.0.10    5678:31889/TCP   14m\n```\n\nThe Envoy container will have an ephemeral port (e.g., `42381`) mapped to the\n`LoadBalancer`'s port `5678`.\n\n```\n> podman ps\nCONTAINER ID  IMAGE                                                                                           COMMAND               CREATED         STATUS         PORTS                                              NAMES\nd261abc4b540  docker.io/envoyproxy/envoy:v1.30.1                                                              bash -c echo -en ...  21 seconds ago  Up 22 seconds  0.0.0.0:42381->5678/tcp, 0.0.0.0:36673->10000/tcp  kindccm-TLRDKPBWWH4DUSI7J7BNE3ABETEPCKSYA6UIWR5B\n```\n\nUse this ephemeral port to connect to the service.\n\n```\ncurl localhost:42381\n```\n"
  },
  {
    "path": "docs/user/example/service_expose_via_loadbalancer.md",
    "content": "### Creating a Service and exposing it via a LoadBalancer\n\nLet's create an application that listens on port 8080 and expose it in the port 80 using a LoadBalancer.\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: policy-local\n  labels:\n    app: MyLocalApp\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: MyLocalApp\n  template:\n    metadata:\n      labels:\n        app: MyLocalApp\n    spec:\n      containers:\n        - name: agnhost\n          image: registry.k8s.io/e2e-test-images/agnhost:2.40\n          args:\n            - netexec\n            - --http-port=8080\n            - --udp-port=8080\n          ports:\n            - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: lb-service-local\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: MyLocalApp\n  ports:\n    - protocol: TCP\n      port: 80\n      targetPort: 8080\n```\n\n```sh\n$ kubectl apply -f examples/loadbalancer_etp_local.yaml\ndeployment.apps/policy-local created\nservice/lb-service-local created\n$ kubectl get service/lb-service-local\nNAME               TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\nlb-service-local   LoadBalancer   10.96.207.137   192.168.8.7   80:31215/TCP   57s\n```\n\nWe can see how the `EXTERNAL-IP` field contains an IP, and we can use it to connect to our\napplication.\n\n```\n$ curl  192.168.8.7:80/hostname\npolicy-local-59854877c9-xwtfk\n\n$  kubectl get pods\nNAME                            READY   STATUS    RESTARTS   AGE\npolicy-local-59854877c9-xwtfk   1/1     Running   0          2m38s\n```"
  },
  {
    "path": "docs/user/gateway/allow_load_balancer_access_control_plane.md",
    "content": "### Allowing load balancers access to control plane nodes\n\nBy default, [Kubernetes expects workloads will not run on control plane nodes](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#control-plane-node-isolation)\nand labels them with [`node.kubernetes.io/exclude-from-external-load-balancers`](https://kubernetes.io/docs/reference/labels-annotations-taints/#node-kubernetes-io-exclude-from-external-load-balancers),\nwhich stops load balancers from accessing them.\n\nIf you are running workloads on control plane nodes, as is the [default kind configuration](https://kind.sigs.k8s.io/docs/user/configuration/#nodes),\nyou will need to remove this label to access them using a LoadBalancer:\n\n```sh\n$ kubectl label node kind-control-plane node.kubernetes.io/exclude-from-external-load-balancers-\n```\n"
  },
  {
    "path": "docs/user/gateway/configure_proxy_image_registry.md",
    "content": "### Configuring Proxy Image Registry\n\n> [!WARNING]\n> The proxy image is an implementation detail of `cloud-provider-kind` and it is not guaranteed to be stable.\n> Changing the image version or tag is not supported and may break the cloud provider.\n> Use the following instructions only for mirroring the image to a private registry.\n\nYou can check the image used by the current version of `cloud-provider-kind` running:\n\n```sh\nbin/cloud-provider-kind list-images\n```\n\nIf you need to mirror the image to a private registry, you can override the registry URL using the `CLOUD_PROVIDER_KIND_REGISTRY_URL` environment variable.\nThis will use the same image name and tag but with the specified registry.\n\nExample of use mirror registry:\n\n```sh\nCLOUD_PROVIDER_KIND_REGISTRY_URL=\"<your-mirror-registry-url>\" bin/cloud-provider-kind\n```"
  },
  {
    "path": "docs/user/gateway/gatewayapi.md",
    "content": "## Gateway API support\n\nThis provider has support for the [Gateway API](https://gateway-api.sigs.k8s.io/).\nIt implements the `Gateway` and `HTTPRoute` functionalities and passes the community conformance tests.\n\nThe Gateway API controller is enabled by default using the standard channel,\nbut you can select the Gateway API release channel (standard/experimental) or just disable the feature completely\nusing the flag `gateway-channel`:\n\n```sh\ncloud-provider-kind --gateway-channel standard|experimental|disabled\n```"
  },
  {
    "path": "docs/user/gateway/running_the_provider.md",
    "content": "### Running the provider\n\nOnce the cluster is running, we need to run the `cloud-provider-kind` in a terminal and keep it running. The `cloud-provider-kind` will monitor all your KIND clusters and `Services` with Type `LoadBalancer` and create the corresponding LoadBalancer containers that will expose those Services.\n\n```sh\nbin/cloud-provider-kind\nI0416 19:58:18.391222 2526219 controller.go:98] Creating new cloud provider for cluster kind\nI0416 19:58:18.398569 2526219 controller.go:105] Starting service controller for cluster kind\nI0416 19:58:18.399421 2526219 controller.go:227] Starting service controller\nI0416 19:58:18.399582 2526219 shared_informer.go:273] Waiting for caches to sync for service\nI0416 19:58:18.500460 2526219 shared_informer.go:280] Caches are synced for service\n...\n```"
  },
  {
    "path": "docs/user/howto.md",
    "content": "## How to use it\n\nRun a KIND cluster:\n\n```sh\n$ kind create cluster\nCreating cluster \"kind\" ...\n ✓ Ensuring node image (kindest/node:v1.26.0) 🖼\n ✓ Preparing nodes 📦\n ✓ Writing configuration 📜\n ✓ Starting control-plane 🕹️\n ✓ Installing CNI 🔌\n ✓ Installing StorageClass 💾\nSet kubectl context to \"kind-kind\"\nYou can now use your cluster with:\n\nkubectl cluster-info --context kind-kind\n\nHave a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂\n\n```"
  },
  {
    "path": "docs/user/ingress/ingress.md",
    "content": "## Compatibility：\nThis guide applies to [cloud-provider-kind](https://github.com/kubernetes-sigs/cloud-provider-kind) v0.9.0+. For older versions, refer to historical docs.\n\n## Setting Up Ingress\n\nIngress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.\n\nSince cloud-provider-kind v0.9.0, it natively supports Ingress. No third-party ingress controllers are required by default.\n\nFor third-party ingress solutions (e.g., Ingress NGINX, Contour), please follow their official documentation.\n\n> **NOTE**: Gateway API is also natively supported (along with Ingress). See the official [Ingress migration guide](https://gateway-api.sigs.k8s.io/guides/migrating-from-ingress/) for details.\n\n## Create Cluster\n\n> **WARNING**: If you are using a [rootless container runtime], ensure your host is\n> properly configured before creating the KIND cluster. Most Ingress and Gateway controllers will\n> not work if these steps are skipped.\n\nCreate a kind cluster and run [Cloud Provider KIND] that automatically enables LoadBalancer support for Ingress. Create a cluster as follows.\n\n```bash\nkind create cluster\n```\n\n## Using Ingress\n\nThe following example creates simple http-echo services and an Ingress object to route to these services.\n\n```yaml\nkind: Pod\napiVersion: v1\nmetadata:\n  name: foo-app\n  labels:\n    app: foo\nspec:\n  containers:\n  - command:\n    - /agnhost\n    - serve-hostname\n    - --http=true\n    - --port=8080\n    image: registry.k8s.io/e2e-test-images/agnhost:2.39\n    name: foo-app\n---\nkind: Service\napiVersion: v1\nmetadata:\n  name: foo-service\nspec:\n  selector:\n    app: foo\n  ports:\n  # Default port used by the image\n  - port: 8080\n---\nkind: Pod\napiVersion: v1\nmetadata:\n  name: bar-app\n  labels:\n    app: bar\nspec:\n  containers:\n  - command:\n    - /agnhost\n    - serve-hostname\n    - --http=true\n    - --port=8080\n    image: registry.k8s.io/e2e-test-images/agnhost:2.39\n    name: bar-app\n---\nkind: Service\napiVersion: v1\nmetadata:\n  name: bar-service\nspec:\n  selector:\n    app: bar\n  ports:\n  # Default port used by the image\n  - port: 8080\n---\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: example-ingress\nspec:\n  rules:\n  - http:\n      paths:\n      - pathType: Prefix\n        path: /foo\n        backend:\n          service:\n            name: foo-service\n            port:\n              number: 8080\n      - pathType: Prefix\n        path: /bar\n        backend:\n          service:\n            name: bar-service\n            port:\n              number: 8080\n---\n```\n\nApply the configuration:\n\n```bash\nkubectl apply -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml\n```\n\n### Verify Ingress Works\n\nCheck the External IP assigned to the Ingress by the built-in LoadBalancer.\n\n```bash\nkubectl get ingress\nNAME              CLASS     HOSTS         ADDRESS        PORTS   AGE\nexample-ingress   <none>    example.com   172.18.0.5     80      10m\n```\n\n\n# get the Ingress IP\n\n```bash\nINGRESS_IP=$(kubectl get ingress example-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')\n\n# should output \"foo-app\"\n\ncurl ${INGRESS_IP}/foo\n\n# should output \"bar-app\"\ncurl ${INGRESS_IP}/bar\n```\n\n[LoadBalancer]: /docs/user/loadbalancer/\n[Cloud Provider KIND]: /docs/user/loadbalancer/\n[rootless container runtime]: /docs/user/rootless/"
  },
  {
    "path": "docs/user/install/install_docker.md",
    "content": "### Running via Docker Image\n\nStarting with v0.4.0, the docker image for cloud-provider-kind is available\nat `registry.k8s.io/cloud-provider-kind/cloud-controller-manager`\n\nYou can also build it locally:\n\n```sh\ngit clone https://github.com/kubernetes-sigs/cloud-provider-kind.git\nCloning into 'cloud-provider-kind'...\nremote: Enumerating objects: 6779, done.\nremote: Counting objects: 100% (6779/6779), done.\nremote: Compressing objects: 100% (4225/4225), done.q\nremote: Total 6779 (delta 2150), reused 6755 (delta 2135), pack-reused 0\nReceiving objects: 100% (6779/6779), 9.05 MiB | 1.83 MiB/s, done.\nResolving deltas: 100% (2150/2150), done.\n\ncd cloud-provider-kind && make\nsudo mv ./bin/cloud-provider-kind  /usr/local/bin/cloud-provider-kind\n```\n\nAnother alternative is to run it as a container, but this will require to mount\nthe docker socket inside the container:\n\n```sh\ndocker build . -t cloud-provider-kind\n# using the host network\ndocker run --rm --network host -v /var/run/docker.sock:/var/run/docker.sock cloud-provider-kind\n# or the kind network\ndocker run --rm --network kind -v /var/run/docker.sock:/var/run/docker.sock cloud-provider-kind\n```\n\nOr using `compose.yaml` file:\n\n```sh\n# using the `kind` network (`host` is the default value for NET_MODE)\nNET_MODE=kind docker compose up -d\n```"
  },
  {
    "path": "docs/user/install/install_go.md",
    "content": "### Installing with `go install`\n\nYou can install `cloud-provider-kind` using `go install`:\n\n```sh\ngo install sigs.k8s.io/cloud-provider-kind@latest\n```\n\nThis will install the binary in `$GOBIN` (typically `~/go/bin`); you\ncan make it available elsewhere if appropriate:\n\n```sh\nsudo install ~/go/bin/cloud-provider-kind /usr/local/bin\n```\n\n### Installing With A Package Manager\n\nThe cloud-provider-kind community has enabled installation via the following package managers.\n\n> [!NOTE]\n> The following are community supported efforts. The `cloud-provider-kind` maintainers are not involved in the creation of these packages, and the upstream community makes no claims on the validity, safety, or content of them.\n\nOn macOS via Homebrew:\n\n```sh\nbrew install cloud-provider-kind\n```"
  },
  {
    "path": "docs/user/os_support.md",
    "content": "### Mac, Windows and WSL2 support\n\nMac and Windows run the containers inside a VM and, on the contrary to Linux, the KIND nodes are not reachable from the host,\nso the LoadBalancer assigned IP is not working for users.\n\nTo solve this problem, cloud-provider-kind, leverages the existing docker portmap capabilities to expose the Loadbalancer IP and Ports\non the host. When you start cloud-provider-kind and create a LoadBalancer service, you will notice that a container named `kindccm-...` is launched within Docker. You can access the service by using the port exposed from the container to the host machine with `localhost`.\n\nFor WSL2, it is recommended to use the default [NAT](https://learn.microsoft.com/en-us/windows/wsl/networking) network mode with Docker Desktop on Windows. On WSL2, you can access the service via the external IP. On Windows, you can access the service by leveraging Docker's portmap capabilities.\n\nLimitations:\n\n- Mutation of Services, adding or removing ports to an existing Services, is not supported.\n- cloud-provider-kind binary needs permissions to add IP address to interfaces and to listen on privileged ports.\n- Overlapping IP between the containers and the host can break connectivity.\n\nMainly tested with `docker` and `Linux`, though `Windows`, `Mac` and `WSL2` are also basically supported:\n\n- On macOS and WSL2 you must run cloud-provider-kind using `sudo`\n- On Windows you must run cloud-provider-kind from a shell that uses `Run as administrator`\n- Further feedback from users will be helpful to support other related platforms."
  },
  {
    "path": "docs/user/support/os_support.md",
    "content": "### Mac, Windows and WSL2 support\n\nMac and Windows run the containers inside a VM and, on the contrary to Linux, the KIND nodes are not reachable from the host,\nso the LoadBalancer assigned IP is not working for users.\n\nTo solve this problem, cloud-provider-kind, leverages the existing docker portmap capabilities to expose the Loadbalancer IP and Ports\non the host. When you start cloud-provider-kind and create a LoadBalancer service, you will notice that a container named `kindccm-...` is launched within Docker. You can access the service by using the port exposed from the container to the host machine with `localhost`.\n\nFor WSL2, it is recommended to use the default [NAT](https://learn.microsoft.com/en-us/windows/wsl/networking) network mode with Docker Desktop on Windows. On WSL2, you can access the service via the external IP. On Windows, you can access the service by leveraging Docker's portmap capabilities.\n\nLimitations:\n\n- Mutation of Services, adding or removing ports to an existing Services, is not supported.\n- cloud-provider-kind binary needs permissions to add IP address to interfaces and to listen on privileged ports.\n- Overlapping IP between the containers and the host can break connectivity.\n\nMainly tested with `docker` and `Linux`, though `Windows`, `Mac` and `WSL2` are also basically supported:\n\n- On macOS and WSL2 you must run cloud-provider-kind using `sudo`\n- On Windows you must run cloud-provider-kind from a shell that uses `Run as administrator`\n- Further feedback from users will be helpful to support other related platforms.\n\n**Note**\n\nThe project is still in very alpha state, bugs are expected, please report them back opening a Github issue.\n"
  },
  {
    "path": "examples/gateway_httproute_simple.yaml",
    "content": "apiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n  name: prod-web\nspec:\n  gatewayClassName: cloud-provider-kind\n  listeners:\n  - protocol: HTTP\n    port: 80\n    name: prod-web-gw\n    allowedRoutes:\n      namespaces:\n        from: Same\n---\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: foo\nspec:\n  parentRefs:\n  - name: prod-web\n  rules:\n  - backendRefs:\n    - name: myapp-svc\n      port: 8080\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: myapp\nspec:\n  selector:\n    matchLabels:\n      app: MyApp\n  replicas: 1\n  template:\n    metadata:\n      labels:\n        app: MyApp\n    spec:\n      containers:\n      - name: myapp\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=80\n          - --delay-shutdown=30\n        ports:\n          - name: httpd\n            containerPort: 80\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: myapp-svc\nspec:\n  type: ClusterIP\n  selector:\n    app: MyApp\n  ports:\n    - name: httpd\n      port: 8080\n      targetPort: 80\n"
  },
  {
    "path": "examples/ingress_foo_bar.yaml",
    "content": "kind: Pod\napiVersion: v1\nmetadata:\n  name: foo-app\n  labels:\n    app: foo\nspec:\n  containers:\n  - command:\n    - /agnhost\n    - netexec\n    - --http-port=8080\n    image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n    name: foo-app\n---\nkind: Service\napiVersion: v1\nmetadata:\n  name: foo-service\nspec:\n  selector:\n    app: foo\n  ports:\n  - port: 8080\n---\nkind: Pod\napiVersion: v1\nmetadata:\n  name: bar-app\n  labels:\n    app: bar\nspec:\n  containers:\n  - command:\n    - /agnhost\n    - netexec\n    - --http-port=8080\n    image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n    name: bar-app\n---\nkind: Service\napiVersion: v1\nmetadata:\n  name: bar-service\nspec:\n  selector:\n    app: bar\n  ports:\n  - port: 8080\n---\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: example-ingress\nspec:\n  rules:\n  - host: foo.example.com\n    http:\n      paths:\n      - pathType: Prefix\n        path: /\n        backend:\n          service:\n            name: foo-service\n            port:\n              number: 8080\n  - host: bar.example.com\n    http:\n      paths:\n      - pathType: Prefix\n        path: /\n        backend:\n          service:\n            name: bar-service\n            port:\n              number: 8080\n---\nkind: Pod\napiVersion: v1\nmetadata:\n  name: curl-pod\nspec:\n  containers:\n  - name: curl\n    image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n"
  },
  {
    "path": "examples/loadbalancer_affinity.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: affinity\nspec:\n  selector:\n    matchLabels:\n      app: affinity\n  replicas: 2\n  strategy:\n    rollingUpdate:\n      maxSurge: 0\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: affinity\n    spec:\n      terminationGracePeriodSeconds: 30\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchExpressions:\n              - key: app\n                operator: In\n                values:\n                - affinity\n            topologyKey: kubernetes.io/hostname\n      containers:\n      - name: affinity\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=80\n          - --delay-shutdown=30\n        ports:\n          - name: httpd\n            containerPort: 80\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: affinity\nspec:\n  type: LoadBalancer\n  sessionAffinity: ClientIP\n  selector:\n    app: affinity\n  ports:\n    - name: httpd\n      port: 80\n      targetPort: 80\n"
  },
  {
    "path": "examples/loadbalancer_deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: zeroapp\nspec:\n  selector:\n    matchLabels:\n      app: zeroapp\n  replicas: 2\n  strategy:\n    rollingUpdate:\n      maxSurge: 0\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: zeroapp\n    spec:\n      terminationGracePeriodSeconds: 30\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchExpressions:\n              - key: app\n                operator: In\n                values:\n                - zeroapp\n            topologyKey: kubernetes.io/hostname\n      containers:\n      - name: zeroapp\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=80\n          - --delay-shutdown=30\n        ports:\n          - name: httpd\n            containerPort: 80\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: zeroapp\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: zeroapp\n  ports:\n    - name: httpd\n      port: 80\n      targetPort: 80\n"
  },
  {
    "path": "examples/loadbalancer_etp_cluster.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: policy-cluster\n  labels:\n    app: MyClusterApp\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: MyClusterApp\n  template:\n    metadata:\n      labels:\n        app: MyClusterApp\n    spec:\n      containers:\n      - name: agnhost\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=8080\n          - --udp-port=8080\n        ports:\n        - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: lb-service-cluster\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Cluster\n  selector:\n    app: MyClusterApp\n  ports:\n    - protocol: TCP\n      port: 80\n      targetPort: 8080"
  },
  {
    "path": "examples/loadbalancer_etp_local.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: policy-local\n  labels:\n    app: MyLocalApp\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: MyLocalApp\n  template:\n    metadata:\n      labels:\n        app: MyLocalApp\n    spec:\n      containers:\n      - name: agnhost\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=8080\n          - --udp-port=8080\n        ports:\n        - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: lb-service-local\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: MyLocalApp\n  ports:\n    - protocol: TCP\n      port: 80\n      targetPort: 8080"
  },
  {
    "path": "examples/loadbalancer_multiport.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: multiport\nspec:\n  selector:\n    matchLabels:\n      app: multiport\n  replicas: 2\n  strategy:\n    rollingUpdate:\n      maxSurge: 0\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: multiport\n    spec:\n      terminationGracePeriodSeconds: 30\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchExpressions:\n              - key: app\n                operator: In\n                values:\n                - multiport\n            topologyKey: kubernetes.io/hostname\n      containers:\n      - name: multiport\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - porter\n        env:\n        - name: SERVE_PORT_80\n          value: \"80\"\n        - name: SERVE_TLS_PORT_443\n          value: \"443\"\n        ports:\n          - name: http\n            containerPort: 80\n          - name: https\n            containerPort: 443\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: multiport\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: multiport\n  ports:\n    - name: http\n      port: 80\n      targetPort: 80\n    - name: https\n      port: 443\n      targetPort: 443\n"
  },
  {
    "path": "examples/loadbalancer_static_ip.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: static-ip\nspec:\n  selector:\n    matchLabels:\n      app: static-ip\n  replicas: 1\n  strategy:\n    rollingUpdate:\n      maxSurge: 0\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: static-ip\n    spec:\n      terminationGracePeriodSeconds: 30\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            - labelSelector:\n                matchExpressions:\n                  - key: app\n                    operator: In\n                    values:\n                      - static-ip\n              topologyKey: kubernetes.io/hostname\n      containers:\n        - name: static-ip\n          image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n          args:\n            - netexec\n            - --http-port=80\n          ports:\n            - name: tcp\n              containerPort: 80\n              protocol: TCP\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: static-ip\nspec:\n  type: LoadBalancer\n  loadBalancerIP: REPLACE_WITH_STATIC_IP\n  selector:\n    app: static-ip\n  ports:\n    - name: tcp\n      port: 80\n      targetPort: 80\n      protocol: TCP"
  },
  {
    "path": "examples/loadbalancer_stts.yaml",
    "content": "apiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n  name: apache\nspec:\n  selector:\n    matchLabels:\n      app: apache\n  serviceName: apache\n  replicas: 2\n  template:\n    metadata:\n      labels:\n        app: apache\n    spec:\n      terminationGracePeriodSeconds: 30\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchExpressions:\n              - key: app\n                operator: In\n                values:\n                - nginx\n            topologyKey: kubernetes.io/hostname\n      containers:\n      - name: apache\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=80\n          - --delay-shutdown=30\n        ports:\n          - name: httpd\n            containerPort: 80\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: apache\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: apache\n  ports:\n    - name: httpd\n      port: 80\n      targetPort: 80\n"
  },
  {
    "path": "examples/loadbalancer_udp_tcp.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: multiprotocol\nspec:\n  selector:\n    matchLabels:\n      app: multiprotocol\n  replicas: 1\n  strategy:\n    rollingUpdate:\n      maxSurge: 0\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: multiprotocol\n    spec:\n      terminationGracePeriodSeconds: 30\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchExpressions:\n              - key: app\n                operator: In\n                values:\n                - multiprotocol\n            topologyKey: kubernetes.io/hostname\n      containers:\n      - name: multiprotocol\n        image: registry.k8s.io/e2e-test-images/agnhost:2.63.0\n        args:\n          - netexec\n          - --http-port=80\n          - --udp-port=80\n        ports:\n          - name: tcp\n            containerPort: 80\n            protocol: TCP\n          - name: udp\n            containerPort: 80\n            protocol: UDP\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: multiprotocol\nspec:\n  type: LoadBalancer\n  externalTrafficPolicy: Local\n  selector:\n    app: multiprotocol\n  ports:\n    - name: tcp\n      port: 80\n      targetPort: 80\n      protocol: TCP\n    - name: udp\n      port: 80\n      targetPort: 80\n      protocol: UDP\n"
  },
  {
    "path": "go.mod",
    "content": "module sigs.k8s.io/cloud-provider-kind\n\ngo 1.25.5\n\nrequire (\n\tgithub.com/envoyproxy/go-control-plane v0.14.0\n\tgithub.com/envoyproxy/go-control-plane/envoy v1.37.0\n\tgithub.com/google/go-cmp v0.7.0\n\tgithub.com/lithammer/dedent v1.1.0\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/spf13/cobra v1.10.2\n\tgithub.com/spf13/pflag v1.0.10\n\tgithub.com/vishvananda/netlink v1.3.1\n\tgoogle.golang.org/grpc v1.80.0\n\tgoogle.golang.org/protobuf v1.36.11\n\tk8s.io/api v0.35.3\n\tk8s.io/apimachinery v0.35.3\n\tk8s.io/apiserver v0.35.3\n\tk8s.io/client-go v0.35.3\n\tk8s.io/cloud-provider v0.35.3\n\tk8s.io/component-base v0.35.3\n\tk8s.io/controller-manager v0.35.3\n\tk8s.io/klog/v2 v2.140.0\n\tk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2\n\tsigs.k8s.io/gateway-api v1.5.1\n\tsigs.k8s.io/kind v0.31.0\n)\n\nrequire (\n\tal.essio.dev/pkg/shellescape v1.6.0 // indirect\n\tcel.dev/expr v0.25.1 // indirect\n\tgithub.com/BurntSushi/toml v1.6.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/blang/semver/v4 v4.0.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.13.0 // indirect\n\tgithub.com/envoyproxy/go-control-plane/ratelimit v0.1.0 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect\n\tgithub.com/evanphx/json-patch/v5 v5.9.11 // indirect\n\tgithub.com/fxamacker/cbor/v2 v2.9.0 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.22.4 // indirect\n\tgithub.com/go-openapi/jsonreference v0.21.4 // indirect\n\tgithub.com/go-openapi/swag v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/cmdutils v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/conv v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/fileutils v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/jsonname v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/jsonutils v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/loading v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/mangling v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/netutils v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/stringutils v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/typeutils v0.25.4 // indirect\n\tgithub.com/go-openapi/swag/yamlutils v0.25.4 // indirect\n\tgithub.com/google/gnostic-models v0.7.1 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/pelletier/go-toml v1.9.5 // indirect\n\tgithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/prometheus/client_golang v1.23.2 // indirect\n\tgithub.com/prometheus/client_model v0.6.2 // indirect\n\tgithub.com/prometheus/common v0.67.5 // indirect\n\tgithub.com/prometheus/procfs v0.19.2 // indirect\n\tgithub.com/vishvananda/netns v0.0.5 // indirect\n\tgithub.com/x448/float16 v0.8.4 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.3 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/net v0.50.0 // indirect\n\tgolang.org/x/oauth2 v0.35.0 // indirect\n\tgolang.org/x/sys v0.41.0 // indirect\n\tgolang.org/x/term v0.40.0 // indirect\n\tgolang.org/x/text v0.34.0 // indirect\n\tgolang.org/x/time v0.14.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect\n\tgopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tk8s.io/component-helpers v0.35.3 // indirect\n\tk8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect\n\tsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect\n\tsigs.k8s.io/randfill v1.0.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect\n\tsigs.k8s.io/yaml v1.6.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA=\nal.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=\ncel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=\ngithub.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=\ngithub.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=\ngithub.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=\ngithub.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik=\ngithub.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=\ngithub.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=\ngithub.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU=\ngithub.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ=\ngithub.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A=\ngithub.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=\ngithub.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=\ngithub.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=\ngithub.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=\ngithub.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=\ngithub.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=\ngithub.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=\ngithub.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=\ngithub.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=\ngithub.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=\ngithub.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=\ngithub.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=\ngithub.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=\ngithub.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=\ngithub.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=\ngithub.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=\ngithub.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=\ngithub.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=\ngithub.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=\ngithub.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=\ngithub.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=\ngithub.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=\ngithub.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=\ngithub.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=\ngithub.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=\ngithub.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=\ngithub.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=\ngithub.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=\ngithub.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=\ngithub.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=\ngithub.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=\ngithub.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=\ngithub.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=\ngithub.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=\ngithub.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=\ngithub.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=\ngithub.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=\ngithub.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=\ngithub.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=\ngithub.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=\ngithub.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=\ngithub.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=\ngithub.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=\ngithub.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=\ngithub.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=\ngithub.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc=\ngithub.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=\ngithub.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=\ngithub.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=\ngithub.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=\ngithub.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=\ngithub.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=\ngithub.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=\ngithub.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=\ngithub.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=\ngithub.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=\ngithub.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=\ngithub.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=\ngithub.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=\ngithub.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=\ngithub.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=\ngithub.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=\ngithub.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=\ngo.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=\ngo.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=\ngo.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngo.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=\ngo.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=\ngolang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=\ngolang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=\ngolang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=\ngolang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=\ngolang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=\ngolang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=\ngolang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=\ngolang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=\ngolang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=\ngolang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=\ngolang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=\ngolang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=\ngolang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=\ngonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=\ngonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=\ngoogle.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=\ngoogle.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=\ngopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nk8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ=\nk8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4=\nk8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8=\nk8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=\nk8s.io/apiserver v0.35.3 h1:D2eIcfJ05hEAEewoSDg+05e0aSRwx8Y4Agvd/wiomUI=\nk8s.io/apiserver v0.35.3/go.mod h1:JI0n9bHYzSgIxgIrfe21dbduJ9NHzKJ6RchcsmIKWKY=\nk8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg=\nk8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c=\nk8s.io/cloud-provider v0.35.3 h1:8gmlIXd9LHhDOXfv0fqsM9KIgVbgl3fwtNI2lDL0qWE=\nk8s.io/cloud-provider v0.35.3/go.mod h1:bHkYmoCLBoyDkx8r8usg0sOo6PIzYrM5qYuDxCyuUxw=\nk8s.io/component-base v0.35.3 h1:mbKbzoIMy7JDWS/wqZobYW1JDVRn/RKRaoMQHP9c4P0=\nk8s.io/component-base v0.35.3/go.mod h1:IZ8LEG30kPN4Et5NeC7vjNv5aU73ku5MS15iZyvyMYk=\nk8s.io/component-helpers v0.35.3 h1:Rl2p3wNMC0YU21rziLkWXavr7MwkB5Td3lNZ/+gYGm8=\nk8s.io/component-helpers v0.35.3/go.mod h1:8BkyfcBA6XsCtFYxDB+mCfZqM6P39Aco12AKigNn0C8=\nk8s.io/controller-manager v0.35.3 h1:BlX95jtN41/vCwuTsmfzR9UpqweX7KDWdwm/mRHez/o=\nk8s.io/controller-manager v0.35.3/go.mod h1:OaG4bXsMfN5zpqowtdyfoRX20LrfwUh6V0zmpF7hw30=\nk8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=\nk8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=\nk8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=\nk8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=\nk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=\nk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=\nsigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0=\nsigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o=\nsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=\nsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=\nsigs.k8s.io/kind v0.31.0 h1:UcT4nzm+YM7YEbqiAKECk+b6dsvc/HRZZu9U0FolL1g=\nsigs.k8s.io/kind v0.31.0/go.mod h1:FSqriGaoTPruiXWfRnUXNykF8r2t+fHtK0P0m1AbGF8=\nsigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=\nsigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=\nsigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=\nsigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=\n"
  },
  {
    "path": "hack/build-route-adder.sh",
    "content": "#!/bin/bash\n\nset -o errexit\nset -o nounset\nset -o pipefail\n\nSCRIPT_DIR=$( cd -- \"$( dirname -- \"${BASH_SOURCE[0]}\" )\" &> /dev/null && pwd )\nREPO_ROOT=$( cd -- \"$SCRIPT_DIR/..\" &> /dev/null && pwd )\n\ncd \"$REPO_ROOT\"\n\nexport CGO_ENABLED=0\n\n# Compile for amd64 (x64)\nGOOS=linux GOARCH=amd64 go build -ldflags=\"-s -w\" -o ./pkg/gateway/routeadder/route-adder-amd64 ./internal/routeadder/\n\n# Compile for arm64\nGOOS=linux GOARCH=arm64 go build -ldflags=\"-s -w\" -o ./pkg/gateway/routeadder/route-adder-arm64 ./internal/routeadder/\n\n# Cleanup is handled by the trap\nexit 0\n"
  },
  {
    "path": "hack/ci/add-kubernetes-to-workspace.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2024 The Kubernetes Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\nset -x\n\nREPO_ROOT=$(git rev-parse --show-toplevel)\nKUBERNETES_ROOT=${KUBERNETES_ROOT:-$GOPATH/src/k8s.io/kubernetes}\ncd ${REPO_ROOT}\n\n# Set up go workspace to build with this version\ngo work init\n\ngo work use .\n\n# Add kubernetes to workspace\ngo work use ${KUBERNETES_ROOT}\nfor d in ${KUBERNETES_ROOT}/staging/src/k8s.io/*; do\n  go work use $d\ndone\n\n# Workaround for go.mod replacements\nsed -i 's/^\\s*k8s.io.*//g' go.mod\ngo work sync\n"
  },
  {
    "path": "hack/ci/e2e.sh",
    "content": "#!/bin/sh\n# Copyright 2018 The Kubernetes Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# hack script for running a kind e2e\n# must be run with a kubernetes checkout in $PWD (IE from the checkout)\n# Usage: SKIP=\"ginkgo skip regex\" FOCUS=\"ginkgo focus regex\" kind-e2e.sh\n\nset -o errexit -o nounset -o xtrace\n\n# Settings:\n# SKIP: ginkgo skip regex\n# FOCUS: ginkgo focus regex\n\n# cleanup logic for cleanup on exit\nCLEANED_UP=false\ncleanup() {\n  if [ \"$CLEANED_UP\" = \"true\" ]; then\n    return\n  fi\n  # KIND_CREATE_ATTEMPTED is true once we: kind create\n  if [ \"${KIND_CREATE_ATTEMPTED:-}\" = true ]; then\n    kind \"export\" logs \"${ARTIFACTS}\" || true\n    kind delete cluster || true\n  fi\n  rm -f _output/bin/e2e.test || true\n  # remove our tempdir, this needs to be last, or it will prevent kind delete\n  if [ -n \"${TMP_DIR:-}\" ]; then\n    rm -rf \"${TMP_DIR:?}\"\n  fi\n  CLEANED_UP=true\n}\n\n# setup signal handlers\n# shellcheck disable=SC2317 # this is not unreachable code\nsignal_handler() {\n  if [ -n \"${GINKGO_PID:-}\" ]; then\n    kill -TERM \"$GINKGO_PID\" || true\n  fi\n  cleanup\n}\ntrap signal_handler INT TERM\n\n# build kubernetes / node image, e2e binaries\nbuild() {\n  # build the node image w/ kubernetes\n  kind build node-image -v 1\n  # Ginkgo v1 is used by Kubernetes 1.24 and earlier, fallback if v2 is not available.\n  GINKGO_SRC_DIR=\"vendor/github.com/onsi/ginkgo/v2/ginkgo\"\n  if [ ! -d \"$GINKGO_SRC_DIR\" ]; then\n      GINKGO_SRC_DIR=\"vendor/github.com/onsi/ginkgo/ginkgo\"\n  fi\n  # make sure we have e2e requirements\n  make all WHAT=\"cmd/kubectl test/e2e/e2e.test ${GINKGO_SRC_DIR}\"\n}\n\n# up a cluster with kind\ncreate_cluster() {\n  # Grab the version of the cluster we're about to start\n  KUBE_VERSION=\"$(docker run --rm --entrypoint=cat \"kindest/node:latest\" /kind/version)\"\n\n  # Default Log level for all components in test clusters\n  KIND_CLUSTER_LOG_LEVEL=${KIND_CLUSTER_LOG_LEVEL:-4}\n\n\n  # JSON or YAML map injected into featureGates config\n  feature_gates=\"${FEATURE_GATES:-{\\}}\"\n  # --runtime-config argument value passed to the API server, again as a map\n  runtime_config=\"${RUNTIME_CONFIG:-{\\}}\"\n\n  # create the config file\n  cat <<EOF > \"${ARTIFACTS}/kind-config.yaml\"\n# config for 1 control plane node and 2 workers (necessary for conformance)\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\nnetworking:\n  ipFamily: ${IP_FAMILY:-ipv4}\n  kubeProxyMode: ${KUBE_PROXY_MODE:-iptables}\n  # don't pass through host search paths\n  # TODO: possibly a reasonable default in the future for kind ...\n  dnsSearch: []\nnodes:\n- role: control-plane\n- role: worker\n- role: worker\nfeatureGates: ${feature_gates}\nruntimeConfig: ${runtime_config}\nkubeadmConfigPatches:\n- |\n  kind: ClusterConfiguration\n  metadata:\n    name: config\n  apiServer:\n    extraArgs:\n      v: \"${KIND_CLUSTER_LOG_LEVEL}\"\n  controllerManager:\n    extraArgs:\n      cloud-provider: \"external\"\n      v: \"${KIND_CLUSTER_LOG_LEVEL}\"\n  ---\n  kind: InitConfiguration\n  nodeRegistration:\n    kubeletExtraArgs:\n      cloud-provider: \"external\"\n      v: \"${KIND_CLUSTER_LOG_LEVEL}\"\n  ---\n  kind: JoinConfiguration\n  nodeRegistration:\n    kubeletExtraArgs:\n      cloud-provider: \"external\"\n      v: \"${KIND_CLUSTER_LOG_LEVEL}\"\nEOF\n  # NOTE: must match the number of workers above\n  NUM_NODES=2\n  # actually create the cluster\n  # TODO(BenTheElder): settle on verbosity for this script\n  KIND_CREATE_ATTEMPTED=true\n  kind create cluster \\\n    --image=kindest/node:latest \\\n    --retain \\\n    --wait=1m \\\n    -v=3 \\\n    \"--config=${ARTIFACTS}/kind-config.yaml\"\n\n  # debug cluster version\n  kubectl version\n\n  # Patch kube-proxy to set the verbosity level\n  kubectl patch -n kube-system daemonset/kube-proxy \\\n    --type='json' -p='[{\"op\": \"add\", \"path\": \"/spec/template/spec/containers/0/command/-\", \"value\": \"--v='\"${KIND_CLUSTER_LOG_LEVEL}\"'\" }]'\n}\n\n# run e2es with ginkgo-e2e.sh\nrun_tests() {\n  # IPv6 clusters need some CoreDNS changes in order to work in k8s CI:\n  # 1. k8s CI doesn´t offer IPv6 connectivity, so CoreDNS should be configured\n  # to work in an offline environment:\n  # https://github.com/coredns/coredns/issues/2494#issuecomment-457215452\n  # 2. k8s CI adds following domains to resolv.conf search field:\n  # c.k8s-prow-builds.internal google.internal.\n  # CoreDNS should handle those domains and answer with NXDOMAIN instead of SERVFAIL\n  # otherwise pods stops trying to resolve the domain.\n  if [ \"${IP_FAMILY:-ipv4}\" = \"ipv6\" ]; then\n    # Get the current config\n    original_coredns=$(kubectl get -oyaml -n=kube-system configmap/coredns)\n    echo \"Original CoreDNS config:\"\n    echo \"${original_coredns}\"\n    # Patch it\n    fixed_coredns=$(\n      printf '%s' \"${original_coredns}\" | sed \\\n        -e 's/^.*kubernetes cluster\\.local/& internal/' \\\n        -e '/^.*upstream$/d' \\\n        -e '/^.*fallthrough.*$/d' \\\n        -e '/^.*forward . \\/etc\\/resolv.conf$/d' \\\n        -e '/^.*loop$/d' \\\n    )\n    echo \"Patched CoreDNS config:\"\n    echo \"${fixed_coredns}\"\n    printf '%s' \"${fixed_coredns}\" | kubectl apply -f -\n  fi\n\n  # ginkgo regexes\n  SKIP=\"${SKIP:-\"Feature|Federation|PerformanceDNS|DualStack|Disruptive|Serial|KubeProxy|GCE|Netpol|NetworkPolicy|256.search.list.characters|LoadBalancer.Service.without.NodePort|type.and.ports.of.a.TCP.service|loadbalancer.source.ranges\"}\"\n  FOCUS=\"${FOCUS:-\"\\\\[sig-network\\\\]\"}\"\n  # if we set PARALLEL=true, skip serial tests set --ginkgo-parallel\n  if [ \"${PARALLEL:-false}\" = \"true\" ]; then\n    export GINKGO_PARALLEL=y\n    if [ -z \"${SKIP}\" ]; then\n      SKIP=\"\\\\[Serial\\\\]\"\n    else\n      SKIP=\"\\\\[Serial\\\\]|${SKIP}\"\n    fi\n  fi\n\n  # setting this env prevents ginkgo e2e from trying to run provider setup\n  export KUBERNETES_CONFORMANCE_TEST='y'\n  # setting these is required to make RuntimeClass tests work ... :/\n  export KUBE_CONTAINER_RUNTIME=remote\n  export KUBE_CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock\n  export KUBE_CONTAINER_RUNTIME_NAME=containerd\n  # ginkgo can take forever to exit, so we run it in the background and save the\n  # PID, bash will not run traps while waiting on a process, but it will while\n  # running a builtin like `wait`, saving the PID also allows us to forward the\n  # interrupt\n  # use aws provider to enable cloud-provider tests, aws is just a nullprovider\n  # without any custom logic\n  ./hack/ginkgo-e2e.sh \\\n    \"--num-nodes=${NUM_NODES}\" \\\n    \"--ginkgo.focus=${FOCUS}\" \"--ginkgo.skip=${SKIP}\" \\\n    \"--report-dir=${ARTIFACTS}\" '--disable-log-dump=true' &\n  GINKGO_PID=$!\n  wait \"$GINKGO_PID\"\n}\n\nmain() {\n  # create temp dir and setup cleanup\n  TMP_DIR=$(mktemp -d)\n\n  # ensure artifacts (results) directory exists when not in CI\n  export ARTIFACTS=\"${ARTIFACTS:-${PWD}/_artifacts}\"\n  mkdir -p \"${ARTIFACTS}\"\n\n  # export the KUBECONFIG to a unique path for testing\n  KUBECONFIG=\"${HOME}/.kube/kind-test-config\"\n  export KUBECONFIG\n  echo \"exported KUBECONFIG=${KUBECONFIG}\"\n\n  # debug kind version\n  kind version\n\n  # build cloud-provider-kind\n  make\n  nohup bin/cloud-provider-kind --enable-log-dumping --logs-dir ${ARTIFACTS}/loadbalancers > ${ARTIFACTS}/ccm-kind.log 2>&1 &\n\n  # build kubernetes\n  K8S_PATH=$(find ${GOPATH} -path '*/k8s.io/kubernetes/go.mod' -print -quit)\n  if [ -z \"${K8S_PATH}\" ]; then\n    K8S_PATH=$(find / -path '*/kubernetes/go.mod' -print -quit)\n  fi\n  cd $(dirname ${K8S_PATH})\n\n  build\n  # in CI attempt to release some memory after building\n  if [ -n \"${KUBETEST_IN_DOCKER:-}\" ]; then\n    sync || true\n    echo 1 > /proc/sys/vm/drop_caches || true\n  fi\n\n  # create the cluster and run tests\n  res=0\n  create_cluster || res=$?\n  run_tests || res=$?\n  cleanup || res=$?\n  exit $res\n}\n\nmain\n"
  },
  {
    "path": "hack/download-gateway-crds.sh",
    "content": "#!/bin/bash\n\nset -o errexit\nset -o nounset\nset -o pipefail\n\nSCRIPT_DIR=$( cd -- \"$( dirname -- \"${BASH_SOURCE[0]}\" )\" &> /dev/null && pwd )\nREPO_ROOT=$( cd -- \"$SCRIPT_DIR/..\" &> /dev/null && pwd )\n\nrepo_url=\"https://github.com/kubernetes-sigs/gateway-api\"\n\n# Define the desired git version (tag or branch). Default to 'main'.\n# Can be overridden by setting the GIT_VERSION environment variable.\nGIT_VERSION=\"${GIT_VERSION:-main}\"\n\n# Define the path within the repo where CRDs are located\n# Using 'standard' as it's common, adjust if needed for different versions\ncrd_repo_subdir=\"config/crd\"\n\n# Define the output directory relative to the REPO_ROOT\noutput_dir_rel=\"pkg/gateway/crds\"\noutput_dir_abs=\"$REPO_ROOT/$output_dir_rel\"\n\n# --- Temporary Directory and Cleanup ---\nTEMP_CLONE_DIR=\"\" # Will hold the path to the temporary directory\n\ncleanup() {\n  local exit_code=$? # Capture exit code\n  echo \"Cleaning up...\"\n  if [ -n \"$TEMP_CLONE_DIR\" ] && [ -d \"$TEMP_CLONE_DIR\" ]; then\n    echo \"Removing temporary clone directory $TEMP_CLONE_DIR...\"\n    rm -rf \"$TEMP_CLONE_DIR\"\n  else\n      echo \"No temporary directory to remove.\"\n  fi\n  # Ensure we exit with the original script's exit code\n  exit $exit_code\n}\n\n# Set trap for cleanup on EXIT, ERR, SIGINT, SIGTERM\ntrap cleanup EXIT ERR SIGINT SIGTERM\n\n# Create a temporary directory for the clone\nTEMP_CLONE_DIR=$(mktemp -d -t gateway-api-clone-XXXXXX)\n# Define the actual path where the repo will be cloned inside the temp dir\nrepo_local_path=\"$TEMP_CLONE_DIR/gateway-api\"\n\necho \"Cloning $repo_url (version: $GIT_VERSION) into temporary directory $repo_local_path...\"\n# Use --depth 1 for a shallow clone.\n# --branch works for tags and branches.\n# Use --no-tags to potentially speed up if tags aren't needed beyond the specific version tag.\n# Add --filter=blob:none if supported by git version and remote to further reduce clone size.\ngit clone --branch \"$GIT_VERSION\" --depth 1 \"$repo_url\" \"$repo_local_path\"\nif [ $? -ne 0 ]; then\n    echo \"Error: Failed to clone repository for version '$GIT_VERSION'.\"\n    # Cleanup function will handle removing TEMP_CLONE_DIR via trap\n    exit 1\nfi\necho \"Successfully cloned version '$GIT_VERSION'.\"\n\n# Create the output directory if it doesn't exist\nmkdir -p \"$output_dir_abs\"\n\n# Define the full path to the CRD source directory within the clone\ncrd_source_dir=\"$repo_local_path/$crd_repo_subdir\"\n\n# Check if the source directory exists\nif [ ! -d \"$crd_source_dir\" ]; then\n    echo \"Error: CRD source directory not found: $crd_source_dir (for version: $GIT_VERSION)\"\n    exit 1\nfi\n\necho \"Copying files from: $crd_source_dir (Version: $GIT_VERSION)\"\n\ncp -rf \"$crd_source_dir\"/* \"$output_dir_abs\"\n\necho \"Successfully copied files to the '$output_dir_abs' directory from version $GIT_VERSION.\"\n\n# Cleanup is handled by the trap\nexit 0\n"
  },
  {
    "path": "hack/init-buildx.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2020 The Kubernetes Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -o errexit -o nounset -o pipefail\n\n# We can skip setup if the current builder already has multi-arch\n# AND if it isn't the docker driver, which doesn't work\ncurrent_builder=\"$(docker buildx inspect)\"\n# linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6\nif ! grep -q \"^Driver: docker$\" <<<\"${current_builder}\" && \\\n     grep -q \"linux/amd64\" <<<\"${current_builder}\" && \\\n     grep -q \"linux/arm64\" <<<\"${current_builder}\"; then\n  exit 0\nfi\n\n# Ensure qemu is in binfmt_misc\n# Docker desktop already has these in versions recent enough to have buildx\n# We only need to do this setup on linux hosts\nif [ \"$(uname)\" == 'Linux' ]; then\n  # NOTE: this is pinned to a digest for a reason!\n  docker run --rm --privileged tonistiigi/binfmt:qemu-v7.0.0-28@sha256:66e11bea77a5ea9d6f0fe79b57cd2b189b5d15b93a2bdb925be22949232e4e55 --install all\nfi\n\n# Ensure we use a builder that can leverage it (the default on linux will not)\ndocker buildx rm knp-builder || true\ndocker buildx create --use --name=knp-builder\n"
  },
  {
    "path": "hack/lint.sh",
    "content": "#!/bin/bash\n\nset -o errexit\nset -o nounset\nset -o pipefail\n\nREPO_ROOT=$(dirname \"${BASH_SOURCE[0]}\")/..\n\ncd $REPO_ROOT\ndocker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v2.7.2 golangci-lint run -v\n"
  },
  {
    "path": "internal/routeadder/main.go",
    "content": "// main.go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\n\t\"github.com/vishvananda/netlink\"\n)\n\n// usage: ./route-adder <cidr> <gateway_ip>\nfunc main() {\n\tif len(os.Args) != 3 {\n\t\tfmt.Fprintf(os.Stderr, \"Usage: %s <destination_cidr> <gateway_ip>\\n\", os.Args[0])\n\t\tos.Exit(1)\n\t}\n\n\tcidr := os.Args[1]\n\tgatewayIP := os.Args[2]\n\n\t// Parse the destination CIDR. This gives us the destination network.\n\t_, dstNet, err := net.ParseCIDR(cidr)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Error parsing destination CIDR %s: %v\\n\", cidr, err)\n\t\tos.Exit(1)\n\t}\n\n\t// Parse the gateway IP address.\n\tgw := net.ParseIP(gatewayIP)\n\tif gw == nil {\n\t\tfmt.Fprintf(os.Stderr, \"Error parsing gateway IP %s\\n\", gatewayIP)\n\t\tos.Exit(1)\n\t}\n\n\t// Create the route object\n\troute := &netlink.Route{\n\t\tDst: dstNet,\n\t\tGw:  gw,\n\t}\n\n\t// Use RouteReplace, which is equivalent to `ip route replace`.\n\t// It will add the route if it doesn't exist or update it if it does.\n\tif err := netlink.RouteReplace(route); err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Error replacing route: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\n\tfmt.Printf(\"Successfully replaced route: %s via %s\\n\", cidr, gatewayIP)\n}\n"
  },
  {
    "path": "kind.yaml",
    "content": "kind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\nkubeadmConfigPatches:\n- |\n  kind: ClusterConfiguration\n  apiServer:\n    extraArgs:\n      v: \"5\"\n  controllerManager:\n    extraArgs:\n      cloud-provider: \"external\"\n      v: \"5\"\n  ---\n  kind: InitConfiguration\n  nodeRegistration:\n    kubeletExtraArgs:\n      cloud-provider: \"external\"\n  ---\n  kind: JoinConfiguration\n  nodeRegistration:\n    kubeletExtraArgs:\n      cloud-provider: \"external\"\nnodes:\n- role: control-plane\n- role: worker\n- role: worker\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"sigs.k8s.io/cloud-provider-kind/cmd\"\n)\n\nfunc main() {\n\tcmd.Main()\n}\n"
  },
  {
    "path": "pkg/config/config.go",
    "content": "package config\n\nimport (\n\t\"os\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/constants\"\n)\n\n// DefaultConfig is a global variable that is initialized at startup.\n// Note: Its fields are modified by command-line flags in cmd/app.go.\nvar DefaultConfig = newDefaultConfig()\n\nfunc newDefaultConfig() *Config {\n\tc := &Config{\n\t\tGatewayReleaseChannel: Standard,\n\t\tIngressDefault:        true,\n\t\tProxyImage:            constants.DefaultProxyImageRegistry + \"/\" + constants.DefaultProxyImageName,\n\t}\n\n\tif registry := os.Getenv(\"CLOUD_PROVIDER_KIND_REGISTRY_URL\"); registry != \"\" {\n\t\tc.ProxyImage = registry + \"/\" + constants.DefaultProxyImageName\n\t}\n\n\treturn c\n}\n\n\n\ntype Config struct {\n\tEnableLogDump bool\n\tLogDir        string\n\t// Platforms like Mac or Windows can not access the containers directly\n\t// so we do a double hop, enable container portmapping for the LoadBalancer containter\n\t// and do userspace proxying from the original port to the portmaps.\n\t// If the cloud-provider-kind runs in a container on these platforms only enables portmapping.\n\tLoadBalancerConnectivity Connectivity\n\t// Type of connectivity between the cloud-provider-kind and the clusters\n\tControlPlaneConnectivity Connectivity\n\t// Gateway API Release channel (default stable)\n\t// https://gateway-api.sigs.k8s.io/concepts/versioning/\n\tGatewayReleaseChannel GatewayReleaseChannel\n\tIngressDefault        bool\n\tProxyImage            string\n}\n\ntype Connectivity int\n\nconst (\n\tUnknown Connectivity = iota\n\tDirect\n\tPortmap\n\tTunnel\n)\n\ntype GatewayReleaseChannel string\n\nconst (\n\tStandard     GatewayReleaseChannel = \"standard\"\n\tExperimental GatewayReleaseChannel = \"experimental\"\n\tDisabled     GatewayReleaseChannel = \"disabled\"\n)\n"
  },
  {
    "path": "pkg/constants/constants.go",
    "content": "package constants\n\nconst (\n\tProviderName = \"kind\"\n\t// cloud-provider-kind\n\tContainerPrefix = \"kindccm\"\n\t// DefaultProxyImageRegistry is the default registry for the Envoy proxy image\n\tDefaultProxyImageRegistry = \"docker.io\"\n\t// DefaultProxyImageName is the default Envoy proxy image\n\tDefaultProxyImageName = \"envoyproxy/envoy:v1.33.2\"\n\t// KIND constants\n\tFixedNetworkName = \"kind\"\n\t// NodeCCMLabelKey\n\tNodeCCMLabelKey = \"io.x-k8s.cloud-provider-kind.cluster\"\n\t// LoadBalancerNameLabelKey clustername/serviceNamespace/serviceName\n\tLoadBalancerNameLabelKey = \"io.x-k8s.cloud-provider-kind.loadbalancer.name\"\n\t// GatewayNameLabelKey clustername/gatewayNamespace/gatewayName\n\tGatewayNameLabelKey = \"io.x-k8s.cloud-provider-kind.gateway.name\"\n)\n"
  },
  {
    "path": "pkg/container/container.go",
    "content": "package container\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"k8s.io/klog/v2\"\n\tkindexec \"sigs.k8s.io/kind/pkg/exec\"\n)\n\n// TODO we can do it as in KIND\nvar containerRuntime = \"docker\"\n\n// dockerIsAvailable checks if docker is available in the system\nfunc dockerIsAvailable() bool {\n\tcmd := kindexec.Command(\"docker\", \"-v\")\n\tlines, err := kindexec.OutputLines(cmd)\n\tif err != nil || len(lines) != 1 {\n\t\treturn false\n\t}\n\treturn strings.HasPrefix(lines[0], \"Docker version\")\n}\n\nfunc podmanIsAvailable() bool {\n\tcmd := kindexec.Command(\"podman\", \"-v\")\n\tlines, err := kindexec.OutputLines(cmd)\n\tif err != nil || len(lines) != 1 {\n\t\treturn false\n\t}\n\treturn strings.HasPrefix(lines[0], \"podman version\")\n}\n\nfunc nerdctlIsAvailable() bool {\n\tcmd := kindexec.Command(\"nerdctl\", \"-v\")\n\tlines, err := kindexec.OutputLines(cmd)\n\tif err != nil || len(lines) != 1 {\n\t\t// check finch\n\t\tcmd = kindexec.Command(\"finch\", \"-v\")\n\t\tlines, err = kindexec.OutputLines(cmd)\n\t\tif err != nil || len(lines) != 1 {\n\t\t\treturn false\n\t\t}\n\t\treturn strings.HasPrefix(lines[0], \"finch version\")\n\t}\n\treturn strings.HasPrefix(lines[0], \"nerdctl version\")\n}\n\n// Runtime returns the detected container runtime name.\nfunc Runtime() string {\n\treturn containerRuntime\n}\n\nfunc init() {\n\t// allow to override the container provider as we do in KIND\n\tif p := os.Getenv(\"KIND_EXPERIMENTAL_PROVIDER\"); p != \"\" {\n\t\tcontainerRuntime = p\n\t\treturn\n\t}\n\n\tif dockerIsAvailable() {\n\t\treturn\n\t}\n\tif podmanIsAvailable() {\n\t\tcontainerRuntime = \"podman\"\n\t\treturn\n\t}\n\tif nerdctlIsAvailable() {\n\t\tcontainerRuntime = \"nerdctl\"\n\t\tif _, err := exec.LookPath(\"nerdctl\"); err != nil {\n\t\t\tif _, err := exec.LookPath(\"finch\"); err == nil {\n\t\t\t\tcontainerRuntime = \"finch\"\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc Logs(name string, w io.Writer) error {\n\tcmd := exec.Command(containerRuntime, []string{\"logs\", name}...)\n\tcmd.Stderr = w\n\tcmd.Stdout = w\n\terr := cmd.Run()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get container logs: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc LogDump(containerName string, fileName string) error {\n\tf, err := os.Create(fileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\terr = Logs(containerName, f)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc Create(name string, args []string) error {\n\tif err := exec.Command(containerRuntime, append([]string{\"run\", \"--name\", name}, args...)...).Run(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc Restart(name string) error {\n\tif err := exec.Command(containerRuntime, []string{\"restart\", name}...).Run(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc Delete(name string) error {\n\tif err := exec.Command(containerRuntime, []string{\"rm\", \"-f\", name}...).Run(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc IsRunning(name string) bool {\n\tcmd := exec.Command(containerRuntime, []string{\"ps\", \"-q\", \"-f\", \"name=\" + name}...)\n\toutput, err := cmd.Output()\n\tif err != nil || len(output) == 0 {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc Exist(name string) bool {\n\terr := exec.Command(containerRuntime, []string{\"inspect\", name}...).Run()\n\treturn err == nil\n}\n\nfunc Signal(name string, signal string) error {\n\terr := exec.Command(containerRuntime, []string{\"kill\", \"-s\", signal, name}...).Run()\n\treturn err\n}\n\nfunc Exec(name string, command []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {\n\targs := []string{\"exec\", \"--privileged\"}\n\tif stdin != nil {\n\t\targs = append(args, \"-i\")\n\t}\n\targs = append(args, name)\n\targs = append(args, command...)\n\tcmd := exec.Command(containerRuntime, args...)\n\tif stdin != nil {\n\t\tcmd.Stdin = stdin\n\t}\n\tif stdout != nil {\n\t\tcmd.Stdout = stdout\n\t}\n\tif stderr != nil {\n\t\tcmd.Stderr = stderr\n\t}\n\treturn cmd.Run()\n}\n\nfunc IPs(name string) (ipv4 string, ipv6 string, err error) {\n\t// retrieve the IP address of the node using docker inspect\n\tcmd := kindexec.Command(containerRuntime, \"inspect\",\n\t\t\"-f\", \"{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}\",\n\t\tname, // ... against the \"node\" container\n\t)\n\tlines, err := kindexec.OutputLines(cmd)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to get container details: %w\", err)\n\t}\n\tif len(lines) != 1 {\n\t\treturn \"\", \"\", fmt.Errorf(\"file should only be one line, got %d lines: %w\", len(lines), err)\n\t}\n\tips := strings.Split(lines[0], \",\")\n\tif len(ips) != 2 {\n\t\treturn \"\", \"\", fmt.Errorf(\"container addresses should have 2 values, got %d values\", len(ips))\n\t}\n\treturn ips[0], ips[1], nil\n}\n\n// return a list with the map of the internal port to the external port\nfunc PortMaps(name string) (map[string]string, error) {\n\t// retrieve the IP address of the node using docker inspect\n\tcmd := kindexec.Command(containerRuntime, \"inspect\",\n\t\t\"-f\", \"{{ json .NetworkSettings.Ports }}\",\n\t\tname, // ... against the \"node\" container\n\t)\n\n\tlines, err := kindexec.OutputLines(cmd)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get container details: %w\", err)\n\t}\n\tif len(lines) != 1 {\n\t\treturn nil, fmt.Errorf(\"file should only be one line, got %d lines: %w\", len(lines), err)\n\t}\n\n\ttype portMapping struct {\n\t\tHostPort string `json:\"HostPort\"`\n\t\tHostIP   string `json:\"HostIp\"`\n\t}\n\n\tportMappings := make(map[string][]portMapping)\n\terr = json.Unmarshal([]byte(lines[0]), &portMappings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresult := map[string]string{}\n\tfor k, v := range portMappings {\n\t\tprotocol := \"tcp\"\n\t\tparts := strings.Split(k, \"/\")\n\t\tif len(parts) == 2 {\n\t\t\tprotocol = strings.ToLower(parts[1])\n\t\t}\n\t\tif protocol != \"tcp\" && protocol != \"udp\" {\n\t\t\tklog.Infof(\"skipping protocol %s not supported, only UDP and TCP\", protocol)\n\t\t\tcontinue\n\t\t}\n\n\t\t// TODO we just can get the first entry or look for ip families\n\t\tfor _, pm := range v {\n\t\t\tif pm.HostPort != \"\" {\n\t\t\t\tresult[parts[0]+\"/\"+protocol] = pm.HostPort\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn result, nil\n}\n\nfunc ListByLabel(label string) ([]string, error) {\n\tcmd := kindexec.Command(containerRuntime,\n\t\t\"ps\",\n\t\t\"-a\", // show stopped nodes\n\t\t// filter for nodes with the cluster label\n\t\t\"--filter\", \"label=\"+label,\n\t\t// format to include the cluster name\n\t\t\"--format\", `{{.ID }}`,\n\t)\n\tlines, err := kindexec.OutputLines(cmd)\n\treturn lines, err\n}\n\n// GetLabelValue return the value of the associated label\n// It returns an error if the label value does not exist\nfunc GetLabelValue(name string, label string) (string, error) {\n\tcmd := kindexec.Command(containerRuntime,\n\t\t\"inspect\",\n\t\t\"--format\", fmt.Sprintf(`{{ index .Config.Labels \"%s\"}}`, label),\n\t\tname,\n\t)\n\tlines, err := kindexec.OutputLines(cmd)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif len(lines) != 1 {\n\t\treturn \"\", fmt.Errorf(\"expected 1 line, got %d\", len(lines))\n\t}\n\treturn lines[0], nil\n}\n"
  },
  {
    "path": "pkg/controller/controller.go",
    "content": "package controller\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\tutilfeature \"k8s.io/apiserver/pkg/util/feature\"\n\t\"k8s.io/client-go/informers\"\n\t\"k8s.io/client-go/kubernetes\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n\tcloudprovider \"k8s.io/cloud-provider\"\n\tcloudproviderapi \"k8s.io/cloud-provider/api\"\n\n\tnodecontroller \"k8s.io/cloud-provider/controllers/node\"\n\tservicecontroller \"k8s.io/cloud-provider/controllers/service\"\n\tcontrollersmetrics \"k8s.io/component-base/metrics/prometheus/controllers\"\n\tccmfeatures \"k8s.io/controller-manager/pkg/features\"\n\t\"k8s.io/klog/v2\"\n\n\tgatewayclient \"sigs.k8s.io/gateway-api/pkg/client/clientset/versioned\"\n\tgatewayinformers \"sigs.k8s.io/gateway-api/pkg/client/informers/externalversions\"\n\n\tcpkconfig \"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/constants\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/gateway\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/ingress\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/loadbalancer\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/provider\"\n\t\"sigs.k8s.io/kind/pkg/cluster\"\n)\n\nvar once sync.Once\n\ntype Controller struct {\n\tkind     *cluster.Provider\n\tclusters map[string]*ccm\n}\n\ntype ccm struct {\n\tfactory           informers.SharedInformerFactory\n\tserviceController *servicecontroller.Controller\n\tnodeController    *nodecontroller.CloudNodeController\n\tgatewayController *gateway.Controller\n\tcancelFn          context.CancelFunc\n}\n\nfunc New(provider *cluster.Provider) *Controller {\n\tcontrollersmetrics.Register()\n\treturn &Controller{\n\t\tkind:     provider,\n\t\tclusters: make(map[string]*ccm),\n\t}\n}\n\nfunc (c *Controller) Run(ctx context.Context) {\n\tlogger := klog.FromContext(ctx)\n\tdefer c.cleanup()\n\n\tfor {\n\t\t// get existing kind clusters\n\t\tclusters, err := c.kind.List()\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Error listing clusters, retrying...\")\n\t\t}\n\n\t\t// add new ones\n\t\tfor _, cluster := range clusters {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t}\n\t\t\tlogger := logger.WithValues(\"cluster\", cluster)\n\n\t\t\tlogger.V(3).Info(\"Processing cluster\")\n\t\t\t_, ok := c.clusters[cluster]\n\t\t\tif ok {\n\t\t\t\tlogger.V(3).Info(\"Cluster already exist\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\trestConfig, err := c.getRestConfig(ctx, cluster)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Error(err, \"Failed to create kubeClient\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlogger.V(2).Info(\"Creating new cloud provider\")\n\t\t\tcloud := provider.New(cluster, c.kind)\n\t\t\tccm, err := startCloudControllerManager(ctx, cluster, restConfig, cloud)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Error(err, \"Failed to start cloud controller\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlogger.Info(\"Starting cloud controller\")\n\t\t\tc.clusters[cluster] = ccm\n\t\t}\n\t\t// remove expired ones\n\t\tclusterSet := sets.New(clusters...)\n\t\tfor cluster, ccm := range c.clusters {\n\t\t\t_, ok := clusterSet[cluster]\n\t\t\tif !ok {\n\t\t\t\tlogger.Info(\"Deleting resources\", \"cluster\", cluster)\n\t\t\t\tccm.cancelFn()\n\t\t\t\tdelete(c.clusters, cluster)\n\t\t\t}\n\t\t}\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase <-time.After(30 * time.Second):\n\t\t}\n\t}\n}\n\nfunc (c *Controller) getKubeConfig(cluster string, internal bool) (*rest.Config, error) {\n\tkconfig, err := c.kind.KubeConfig(cluster, internal)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get kubeconfig for cluster %s: %v\", cluster, err)\n\t\treturn nil, err\n\t}\n\n\tconfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kconfig))\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to convert kubeconfig for cluster %s: %v\", cluster, err)\n\t\treturn nil, err\n\t}\n\treturn config, nil\n}\n\n// getRestConfig returns a valid rest.Config for the cluster passed as argument\n// It tries first to connect to the internal endpoint.\nfunc (c *Controller) getRestConfig(ctx context.Context, cluster string) (*rest.Config, error) {\n\tlogger := klog.FromContext(ctx).WithValues(\"cluster\", cluster)\n\n\taddresses := []string{}\n\tinternalConfig, err := c.getKubeConfig(cluster, true)\n\tif err != nil {\n\t\tlogger.Error(err, \"Failed to get internal kubeconfig\")\n\t} else {\n\t\taddresses = append(addresses, internalConfig.Host)\n\t}\n\texternalConfig, err := c.getKubeConfig(cluster, false)\n\tif err != nil {\n\t\tlogger.Error(err, \"Failed to get external kubeconfig\")\n\t} else {\n\t\taddresses = append(addresses, externalConfig.Host)\n\t}\n\n\tif len(addresses) == 0 {\n\t\treturn nil, fmt.Errorf(\"could not find kubeconfig\")\n\t}\n\n\tvar host string\n\tfor i := 0; i < 5; i++ {\n\t\thost, err = firstSuccessfulProbe(ctx, addresses)\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to connect to any address\", \"addresses\", addresses)\n\t\t\ttime.Sleep(time.Second * time.Duration(i))\n\t\t} else {\n\t\t\tlogger.Info(\"Connected succesfully\", \"host\", host)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvar config *rest.Config\n\tswitch host {\n\tcase internalConfig.Host:\n\t\tconfig = internalConfig\n\t\t// the first cluster will give us the type of connectivity between\n\t\t// cloud-provider-kind and the clusters and load balancer containers.\n\t\t// In Linux or containerized cloud-provider-kind this will be direct.\n\t\tonce.Do(func() {\n\t\t\tcpkconfig.DefaultConfig.ControlPlaneConnectivity = cpkconfig.Direct\n\t\t})\n\tcase externalConfig.Host:\n\t\tconfig = externalConfig\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"restConfig for host %s not avaliable\", host)\n\t}\n\n\treturn config, nil\n}\n\n// TODO: implement leader election to not have problems with multiple providers\n// ref: https://github.com/kubernetes/kubernetes/blob/d97ea0f705847f90740cac3bc3dd8f6a4026d0b5/cmd/kube-scheduler/app/server.go#L211\nfunc startCloudControllerManager(ctx context.Context, clusterName string, config *rest.Config, cloud cloudprovider.Interface) (*ccm, error) {\n\tlogger := klog.FromContext(ctx).WithValues(\"cluster\", clusterName)\n\n\t// TODO: we need to set up the ccm specific feature gates\n\t// but try to avoid to expose this to users\n\tfeatureGates := utilfeature.DefaultMutableFeatureGate\n\terr := ccmfeatures.SetupCurrentKubernetesSpecificFeatureGates(featureGates)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkubeClient, err := kubernetes.NewForConfig(config)\n\tif err != nil {\n\t\tlogger.Error(err, \"Failed to create kubeClient\")\n\t\treturn nil, err\n\t}\n\n\tclient := kubeClient.Discovery().RESTClient()\n\t// wait for health\n\terr = wait.PollUntilContextTimeout(ctx, 1*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {\n\t\thealthStatus := 0\n\t\tclient.Get().AbsPath(\"/healthz\").Do(ctx).StatusCode(&healthStatus)\n\t\tif healthStatus != http.StatusOK {\n\t\t\treturn false, nil\n\t\t}\n\n\t\treturn true, nil\n\t})\n\tif err != nil {\n\t\tlogger.Error(err, \"Failed waiting for apiserver to be ready\")\n\t\treturn nil, err\n\t}\n\n\tsharedInformers := informers.NewSharedInformerFactory(kubeClient, 60*time.Second)\n\tservicesInformer := sharedInformers.Core().V1().Services()\n\tnodesInformer := sharedInformers.Core().V1().Nodes()\n\tnamespacesInformer := sharedInformers.Core().V1().Namespaces()\n\tsecretsInformer := sharedInformers.Core().V1().Secrets()\n\tingressInformer := sharedInformers.Networking().V1().Ingresses()\n\tingressClassInformer := sharedInformers.Networking().V1().IngressClasses()\n\n\tccmMetrics := controllersmetrics.NewControllerManagerMetrics(clusterName)\n\t// Start the service controller\n\tserviceController, err := servicecontroller.New(\n\t\tcloud,\n\t\tkubeClient,\n\t\tservicesInformer,\n\t\tnodesInformer,\n\t\tclusterName,\n\t\tfeatureGates,\n\t)\n\tif err != nil {\n\t\t// This error shouldn't fail. It lives like this as a legacy.\n\t\tlogger.Error(err, \"Failed to start service controller\")\n\t\treturn nil, err\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\tgo serviceController.Run(ctx, 5, ccmMetrics)\n\n\tnodeController := &nodecontroller.CloudNodeController{}\n\n\thasCloudProviderTaint, err := getCloudProviderTaint(ctx, clusterName, kubeClient)\n\tif err != nil {\n\t\tlogger.Error(err, \"Failed get cluster nodes\")\n\t\tcancel()\n\t\treturn nil, err\n\t}\n\n\tif hasCloudProviderTaint {\n\t\t// Start the node controller\n\t\tnodeController, err = nodecontroller.NewCloudNodeController(\n\t\t\tnodesInformer,\n\t\t\tkubeClient,\n\t\t\tcloud,\n\t\t\t30*time.Second,\n\t\t\t5, // workers\n\t\t)\n\t\tif err != nil {\n\t\t\t// This error shouldn't fail. It lives like this as a legacy.\n\t\t\tlogger.Error(err, \"Failed to start node controller\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\t\tgo nodeController.Run(ctx.Done(), ccmMetrics)\n\t}\n\n\t// Gateway setup\n\tcrdManager, err := gateway.NewCRDManager(config)\n\tif err != nil {\n\t\tlogger.Error(err, \"Failed to create Gateway API CRD manager\")\n\t\tcancel()\n\t\treturn nil, err\n\t}\n\n\t// Only install CRDs if gateway channel is not disabled\n\tif cpkconfig.DefaultConfig.GatewayReleaseChannel != cpkconfig.Disabled {\n\t\terr = crdManager.InstallCRDs(ctx, cpkconfig.DefaultConfig.GatewayReleaseChannel)\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to install Gateway API CRDs\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tlogger.Info(\"Gateway API CRDs installation skipped (disabled)\")\n\t}\n\n\tvar gatewayController *gateway.Controller\n\n\t// Only set up Gateway API controllers if not disabled\n\tif cpkconfig.DefaultConfig.GatewayReleaseChannel != cpkconfig.Disabled {\n\t\tgwClient, err := gatewayclient.NewForConfig(config)\n\t\tif err != nil {\n\t\t\t// This error shouldn't fail. It lives like this as a legacy.\n\t\t\tlogger.Error(err, \"Failed to create Gateway API client\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\n\t\tsharedGwInformers := gatewayinformers.NewSharedInformerFactory(gwClient, 60*time.Second)\n\t\tgwClassInformer := sharedGwInformers.Gateway().V1().GatewayClasses()\n\t\tgwInformer := sharedGwInformers.Gateway().V1().Gateways()\n\t\thttpRouteInformer := sharedGwInformers.Gateway().V1().HTTPRoutes()\n\t\tgrpcRouteInformer := sharedGwInformers.Gateway().V1().GRPCRoutes()\n\t\treferenceGrantInformer := sharedGwInformers.Gateway().V1().ReferenceGrants()\n\n\t\tgatewayController, err = gateway.New(\n\t\t\tclusterName,\n\t\t\tkubeClient,\n\t\t\tgwClient,\n\t\t\tnamespacesInformer,\n\t\t\tservicesInformer,\n\t\t\tsecretsInformer,\n\t\t\tgwClassInformer,\n\t\t\tgwInformer,\n\t\t\thttpRouteInformer,\n\t\t\tgrpcRouteInformer,\n\t\t\treferenceGrantInformer,\n\t\t)\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to start gateway controller\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Ingress to Gateway controller migration\n\t\tingressController, err := ingress.NewController(\n\t\t\tkubeClient,\n\t\t\tgwClient,\n\t\t\tgateway.GWClassName,\n\t\t\tingressInformer,\n\t\t\tingressClassInformer,\n\t\t\tservicesInformer,\n\t\t\tsecretsInformer,\n\t\t\thttpRouteInformer,\n\t\t\tgwInformer,\n\t\t)\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to create Ingress controller\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\n\t\tsharedInformers.Start(ctx.Done())\n\t\tsharedGwInformers.Start(ctx.Done())\n\n\t\terr = gatewayController.Init(ctx)\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to initialize gateway controller\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\n\t\tgo func() {\n\t\t\t_ = gatewayController.Run(ctx)\n\t\t}()\n\n\t\terr = ingressController.Init(ctx)\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to initialize ingress controller\")\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\n\t\tgo ingressController.Run(ctx, 5)\n\t} else {\n\t\tlogger.Info(\"Gateway API controllers skipped (disabled)\")\n\t\t// Start only the core informers, not gateway informers\n\t\tsharedInformers.Start(ctx.Done())\n\t}\n\n\t// This has to cleanup all the resources allocated by the cloud provider in this cluster\n\t// - containers as loadbalancers\n\t// - in windows and darwin ip addresses on the loopback interface\n\t// Find all the containers associated to the cluster and then use the cloud provider methods to delete\n\t// the loadbalancer, we can extract the service name from the container labels.\n\tcancelFn := func() {\n\t\tcancel()\n\n\t\tcontainers, err := container.ListByLabel(fmt.Sprintf(\"%s=%s\", constants.NodeCCMLabelKey, clusterName))\n\t\tif err != nil {\n\t\t\tlogger.Error(err, \"Failed to list containers\")\n\t\t\treturn\n\t\t}\n\n\t\tlbController, ok := cloud.LoadBalancer()\n\t\t// this can not happen\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\n\t\tfor _, name := range containers {\n\t\t\tlogger.V(2).Info(\"Cleaning up container\", \"container\", name)\n\t\t\tcleanupLoadBalancer(lbController, name)\n\t\t\tcleanupGateway(name)\n\t\t}\n\t}\n\n\treturn &ccm{\n\t\tfactory:           sharedInformers,\n\t\tserviceController: serviceController,\n\t\tnodeController:    nodeController,\n\t\tgatewayController: gatewayController,\n\t\tcancelFn:          cancelFn}, nil\n}\n\n// TODO cleanup alias ip on mac\nfunc (c *Controller) cleanup() {\n\tfor cluster, ccm := range c.clusters {\n\t\tklog.Infof(\"Cleaning resources for cluster %s\", cluster)\n\t\tccm.cancelFn()\n\t\tdelete(c.clusters, cluster)\n\t}\n\t// final cleanup for containers that be left behind\n\tcontainers, err := container.ListByLabel(constants.NodeCCMLabelKey)\n\tif err != nil {\n\t\tklog.Errorf(\"can't list containers: %v\", err)\n\t\treturn\n\t}\n\n\tfor _, name := range containers {\n\t\tklog.V(2).Infof(\"cleaning up container %s\", name)\n\t\terr := container.Delete(name)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"error deleting container %s : %v\", name, err)\n\t\t}\n\t}\n}\n\nfunc getCloudProviderTaint(ctx context.Context, clusterName string, kubeClient kubernetes.Interface) (bool, error) {\n\tnodes, err := kubeClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{})\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to list nodes for cluster %s: %w\", clusterName, err)\n\t}\n\tfor _, node := range nodes.Items {\n\t\tfor _, taint := range node.Spec.Taints {\n\t\t\tif taint.Key == cloudproviderapi.TaintExternalCloudProvider {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc cleanupLoadBalancer(lbController cloudprovider.LoadBalancer, name string) {\n\t// create fake service to pass to the cloud provider method\n\tv, err := container.GetLabelValue(name, constants.LoadBalancerNameLabelKey)\n\tif err != nil || v == \"\" {\n\t\tklog.Infof(\"could not get the label for the loadbalancer on container %s : %v\", name, err)\n\t\treturn\n\t}\n\tclusterName, service := loadbalancer.ServiceFromLoadBalancerSimpleName(v)\n\tif service == nil {\n\t\tklog.Infof(\"invalid format for loadbalancer on cluster %s: %s\", clusterName, v)\n\t\treturn\n\t}\n\terr = lbController.EnsureLoadBalancerDeleted(context.Background(), clusterName, service)\n\tif err != nil {\n\t\tklog.Infof(\"error deleting loadbalancer %s/%s on cluster %s : %v\", service.Namespace, service.Name, clusterName, err)\n\t\treturn\n\t}\n}\n\nfunc cleanupGateway(name string) {\n\t// create fake service to pass to the cloud provider method\n\tv, err := container.GetLabelValue(name, constants.GatewayNameLabelKey)\n\tif err != nil || v == \"\" {\n\t\tklog.Infof(\"could not get the label for the loadbalancer on container %s : %v\", name, err)\n\t\treturn\n\t}\n\terr = container.Delete(name)\n\tif err != nil {\n\t\tklog.Infof(\"error deleting container %s gateway %s : %v\", name, v, err)\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/controller/http.go",
    "content": "package controller\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc probeHTTP(ctx context.Context, address string) bool {\n\tklog.Infof(\"probe HTTP address %s\", address)\n\thttpClient := &http.Client{\n\t\tTimeout: 2 * time.Second,\n\t\tTransport: &http.Transport{\n\t\t\tTLSClientConfig: &tls.Config{InsecureSkipVerify: true},\n\t\t},\n\t}\n\treq, err := http.NewRequest(\"GET\", address, nil)\n\tif err != nil {\n\t\treturn false\n\t}\n\treq = req.WithContext(ctx)\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\tklog.Infof(\"Failed to connect to HTTP address %s: %v\", address, err)\n\t\treturn false\n\t}\n\tdefer resp.Body.Close()\n\t// drain the body\n\tio.ReadAll(resp.Body) // nolint:errcheck\n\t// we only want to verify connectivity so don't need to check the http status code\n\t// as the apiserver may not be ready\n\treturn true\n}\n\n// firstSuccessfulProbe probes the given addresses in parallel and returns the first address to succeed, cancelling the other probes.\nfunc firstSuccessfulProbe(ctx context.Context, addresses []string) (string, error) {\n\tvar wg sync.WaitGroup\n\tresultChan := make(chan string, 1)\n\n\tctx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\tfor _, addr := range addresses {\n\t\twg.Add(1)\n\t\tgo func(address string) {\n\t\t\tdefer wg.Done()\n\t\t\tif probeHTTP(ctx, address) {\n\t\t\t\tselect {\n\t\t\t\tcase resultChan <- address:\n\t\t\t\tdefault:\n\t\t\t\t}\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}(addr)\n\t}\n\n\tgo func() {\n\t\twg.Wait()\n\t\tclose(resultChan)\n\t}()\n\n\tselect {\n\tcase result := <-resultChan:\n\t\treturn result, nil\n\tcase <-ctx.Done():\n\t\treturn \"\", fmt.Errorf(\"no address succeeded\")\n\t}\n}\n"
  },
  {
    "path": "pkg/controller/http_test.go",
    "content": "package controller\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc Test_firstSuccessfulProbe(t *testing.T) {\n\treqCh := make(chan struct{})\n\tts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tt.Logf(\"received connection \")\n\t\tclose(reqCh)\n\t}))\n\tts.EnableHTTP2 = true\n\tts.StartTLS()\n\tdefer ts.Close()\n\t// use an address that is not likely to exist to avoid flakes\n\taddresses := []string{\"https://127.0.1.201:12349\", ts.URL}\n\tgot, err := firstSuccessfulProbe(context.Background(), addresses)\n\tif err != nil {\n\t\tt.Errorf(\"firstSuccessfulProbe() error = %v\", err)\n\t\treturn\n\t}\n\tif got != ts.URL {\n\t\tt.Errorf(\"firstSuccessfulProbe() = %v, want %v\", got, ts.URL)\n\t}\n\n\tselect {\n\tcase <-reqCh:\n\tcase <-time.After(10 * time.Second):\n\t\tt.Fatalf(\"test timed out, no request received\")\n\t}\n\n}\n"
  },
  {
    "path": "pkg/gateway/backendref.go",
    "content": "package gateway\n\nimport (\n\t\"fmt\"\n\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n// backendRefToClusterName generates a unique Envoy cluster name from a Gateway API BackendRef.\n// It returns a structured ControllerError with the appropriate Reason on failure.\nfunc backendRefToClusterName(defaultNamespace string, backendRef gatewayv1.BackendRef) (string, error) {\n\t// 1. Validate that the Kind is a supported type (Service).\n\tif backendRef.Kind != nil && *backendRef.Kind != \"Service\" {\n\t\treturn \"\", &ControllerError{\n\t\t\tReason:  string(gatewayv1.RouteReasonInvalidKind),\n\t\t\tMessage: fmt.Sprintf(\"unsupported backend kind: %s\", *backendRef.Kind),\n\t\t}\n\t}\n\n\t// 2. Validate that the Port is specified.\n\tif backendRef.Port == nil {\n\t\treturn \"\", &ControllerError{\n\t\t\t// Note: There isn't a specific reason for a missing port,\n\t\t\t// so InvalidParameters is a reasonable choice.\n\t\t\tReason:  string(gatewayv1.RouteReasonUnsupportedProtocol),\n\t\t\tMessage: \"backend port must be specified\",\n\t\t}\n\t}\n\n\tnamespace := defaultNamespace\n\tif backendRef.Namespace != nil {\n\t\tnamespace = string(*backendRef.Namespace)\n\t}\n\n\tport := int32(*backendRef.Port)\n\tgroup := \"core\"\n\tif backendRef.Group != nil && *backendRef.Group != \"\" {\n\t\tgroup = string(*backendRef.Group)\n\t}\n\tkind := \"Service\"\n\tif backendRef.Kind != nil && *backendRef.Kind != \"\" {\n\t\tkind = string(*backendRef.Kind)\n\t}\n\n\t// Format: <namespace>_<name>_<group>_<kind>_<port>\n\tclusterName := fmt.Sprintf(\"%s_%s_%s_%s_%d\", namespace, backendRef.Name, group, kind, port)\n\n\treturn clusterName, nil\n}\n"
  },
  {
    "path": "pkg/gateway/backendref_test.go",
    "content": "package gateway\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"k8s.io/utils/ptr\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\nfunc TestBackendRefToClusterName(t *testing.T) {\n\ttests := []struct {\n\t\tname             string\n\t\tdefaultNamespace string\n\t\tbackendRef       gatewayv1.BackendRef\n\t\twantName         string\n\t\twantErr          bool\n\t\twantReason       string\n\t}{\n\t\t{\n\t\t\tname:             \"valid backendRef with all fields\",\n\t\t\tdefaultNamespace: \"default\",\n\t\t\tbackendRef: gatewayv1.BackendRef{\n\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\tName:      \"my-service\",\n\t\t\t\t\tNamespace: ptr.To(gatewayv1.Namespace(\"my-ns\")),\n\t\t\t\t\tGroup:     ptr.To(gatewayv1.Group(\"my-group\")),\n\t\t\t\t\tKind:      ptr.To(gatewayv1.Kind(\"Service\")),\n\t\t\t\t\tPort:      ptr.To(gatewayv1.PortNumber(8080)),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantName:   \"my-ns_my-service_my-group_Service_8080\",\n\t\t\twantErr:    false,\n\t\t\twantReason: \"\",\n\t\t},\n\t\t{\n\t\t\tname:             \"valid backendRef with default fields\",\n\t\t\tdefaultNamespace: \"default\",\n\t\t\tbackendRef: gatewayv1.BackendRef{\n\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\tName: \"my-service\",\n\t\t\t\t\tPort: ptr.To(gatewayv1.PortNumber(80)),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantName:   \"default_my-service_core_Service_80\",\n\t\t\twantErr:    false,\n\t\t\twantReason: \"\",\n\t\t},\n\t\t{\n\t\t\tname:             \"unsupported kind\",\n\t\t\tdefaultNamespace: \"default\",\n\t\t\tbackendRef: gatewayv1.BackendRef{\n\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\tName: \"my-service\",\n\t\t\t\t\tKind: ptr.To(gatewayv1.Kind(\"UnsupportedKind\")),\n\t\t\t\t\tPort: ptr.To(gatewayv1.PortNumber(80)),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantName:   \"\",\n\t\t\twantErr:    true,\n\t\t\twantReason: string(gatewayv1.RouteReasonInvalidKind),\n\t\t},\n\t\t{\n\t\t\tname:             \"missing port\",\n\t\t\tdefaultNamespace: \"default\",\n\t\t\tbackendRef: gatewayv1.BackendRef{\n\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\tName: \"my-service\",\n\t\t\t\t\tPort: nil,\n\t\t\t\t},\n\t\t\t},\n\t\t\twantName:   \"\",\n\t\t\twantErr:    true,\n\t\t\twantReason: string(gatewayv1.RouteReasonUnsupportedProtocol),\n\t\t},\n\t\t{\n\t\t\tname:             \"specified namespace\",\n\t\t\tdefaultNamespace: \"default\",\n\t\t\tbackendRef: gatewayv1.BackendRef{\n\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\tName:      \"my-service\",\n\t\t\t\t\tNamespace: ptr.To(gatewayv1.Namespace(\"other-ns\")),\n\t\t\t\t\tPort:      ptr.To(gatewayv1.PortNumber(80)),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantName:   \"other-ns_my-service_core_Service_80\",\n\t\t\twantErr:    false,\n\t\t\twantReason: \"\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgotName, err := backendRefToClusterName(tt.defaultNamespace, tt.backendRef)\n\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"backendRefToClusterName() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif tt.wantErr {\n\t\t\t\tvar controllerErr *ControllerError\n\t\t\t\tif errors.As(err, &controllerErr) {\n\t\t\t\t\tif controllerErr.Reason != tt.wantReason {\n\t\t\t\t\t\tt.Errorf(\"backendRefToClusterName() error reason = %s, wantReason %s\", controllerErr.Reason, tt.wantReason)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tt.Errorf(\"backendRefToClusterName() expected a ControllerError, but got %T\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif gotName != tt.wantName {\n\t\t\t\tt.Errorf(\"backendRefToClusterName() gotName = %v, want %v\", gotName, tt.wantName)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/gateway/controller.go",
    "content": "/*\nCopyright 2024 The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage gateway\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"sort\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/keepalive\"\n\n\tcorev3 \"github.com/envoyproxy/go-control-plane/envoy/config/core/v3\"\n\tclusterv3service \"github.com/envoyproxy/go-control-plane/envoy/service/cluster/v3\"\n\tdiscoveryv3 \"github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3\"\n\tendpointv3 \"github.com/envoyproxy/go-control-plane/envoy/service/endpoint/v3\"\n\tlistenerv3service \"github.com/envoyproxy/go-control-plane/envoy/service/listener/v3\"\n\troutev3service \"github.com/envoyproxy/go-control-plane/envoy/service/route/v3\"\n\truntimev3 \"github.com/envoyproxy/go-control-plane/envoy/service/runtime/v3\"\n\tsecretv3 \"github.com/envoyproxy/go-control-plane/envoy/service/secret/v3\"\n\tenvoyproxytypes \"github.com/envoyproxy/go-control-plane/pkg/cache/types\"\n\tcachev3 \"github.com/envoyproxy/go-control-plane/pkg/cache/v3\"\n\tresourcev3 \"github.com/envoyproxy/go-control-plane/pkg/resource/v3\"\n\tserverv3 \"github.com/envoyproxy/go-control-plane/pkg/server/v3\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/util/runtime\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\tcorev1informers \"k8s.io/client-go/informers/core/v1\"\n\t\"k8s.io/client-go/kubernetes\"\n\tcorev1listers \"k8s.io/client-go/listers/core/v1\"\n\t\"k8s.io/client-go/tools/cache\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/ptr\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/tunnels\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n\tgatewayclient \"sigs.k8s.io/gateway-api/pkg/client/clientset/versioned\"\n\tgatewayinformers \"sigs.k8s.io/gateway-api/pkg/client/informers/externalversions/apis/v1\"\n\tgatewaylisters \"sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1\"\n)\n\nconst (\n\tcontrollerName = \"kind.sigs.k8s.io/gateway-controller\"\n\tGWClassName    = \"cloud-provider-kind\"\n\tmaxRetries     = 5\n\tworkers        = 5\n)\n\nconst (\n\tgrpcKeepaliveTime        = 30 * time.Second\n\tgrpcKeepaliveTimeout     = 5 * time.Second\n\tgrpcKeepaliveMinTime     = 30 * time.Second\n\tgrpcMaxConcurrentStreams = 1000000\n)\n\ntype ControllerError struct {\n\tReason  string\n\tMessage string\n}\n\n// Error implements the error interface.\nfunc (e *ControllerError) Error() string {\n\treturn e.Message\n}\n\ntype Controller struct {\n\tclusterName       string\n\tclusterNameserver string\n\n\tclient   kubernetes.Interface\n\tgwClient gatewayclient.Interface\n\n\tnamespaceLister       corev1listers.NamespaceLister\n\tnamespaceListerSynced cache.InformerSynced\n\n\tserviceLister       corev1listers.ServiceLister\n\tserviceListerSynced cache.InformerSynced\n\n\tsecretLister       corev1listers.SecretLister\n\tsecretListerSynced cache.InformerSynced\n\n\tgatewayClassLister       gatewaylisters.GatewayClassLister\n\tgatewayClassListerSynced cache.InformerSynced\n\n\tgatewayLister       gatewaylisters.GatewayLister\n\tgatewayListerSynced cache.InformerSynced\n\tgatewayqueue        workqueue.TypedRateLimitingInterface[string]\n\n\thttprouteLister       gatewaylisters.HTTPRouteLister\n\thttprouteListerSynced cache.InformerSynced\n\n\tgrpcrouteLister       gatewaylisters.GRPCRouteLister\n\tgrpcrouteListerSynced cache.InformerSynced\n\n\treferenceGrantLister       gatewaylisters.ReferenceGrantLister\n\treferenceGrantListerSynced cache.InformerSynced\n\n\txdscache        cachev3.SnapshotCache\n\txdsserver       serverv3.Server\n\txdsLocalAddress string\n\txdsLocalPort    int\n\txdsVersion      atomic.Uint64\n\n\ttunnelManager *tunnels.TunnelManager\n}\n\nfunc New(\n\tclusterName string,\n\tclient *kubernetes.Clientset,\n\tgwClient *gatewayclient.Clientset,\n\tnamespaceInformer corev1informers.NamespaceInformer,\n\tserviceInformer corev1informers.ServiceInformer,\n\tsecretInformer corev1informers.SecretInformer,\n\tgatewayClassInformer gatewayinformers.GatewayClassInformer,\n\tgatewayInformer gatewayinformers.GatewayInformer,\n\thttprouteInformer gatewayinformers.HTTPRouteInformer,\n\tgrpcrouteInformer gatewayinformers.GRPCRouteInformer,\n\treferenceGrantInformer gatewayinformers.ReferenceGrantInformer,\n) (*Controller, error) {\n\tc := &Controller{\n\t\tclusterName:              clusterName,\n\t\tclient:                   client,\n\t\tnamespaceLister:          namespaceInformer.Lister(),\n\t\tnamespaceListerSynced:    namespaceInformer.Informer().HasSynced,\n\t\tserviceLister:            serviceInformer.Lister(),\n\t\tserviceListerSynced:      serviceInformer.Informer().HasSynced,\n\t\tsecretLister:             secretInformer.Lister(),\n\t\tsecretListerSynced:       secretInformer.Informer().HasSynced,\n\t\tgwClient:                 gwClient,\n\t\tgatewayClassLister:       gatewayClassInformer.Lister(),\n\t\tgatewayClassListerSynced: gatewayClassInformer.Informer().HasSynced,\n\t\tgatewayLister:            gatewayInformer.Lister(),\n\t\tgatewayListerSynced:      gatewayInformer.Informer().HasSynced,\n\t\tgatewayqueue: workqueue.NewTypedRateLimitingQueueWithConfig(\n\t\t\tworkqueue.DefaultTypedControllerRateLimiter[string](),\n\t\t\tworkqueue.TypedRateLimitingQueueConfig[string]{Name: \"gateway\"},\n\t\t),\n\t\thttprouteLister:            httprouteInformer.Lister(),\n\t\thttprouteListerSynced:      httprouteInformer.Informer().HasSynced,\n\t\tgrpcrouteLister:            grpcrouteInformer.Lister(),\n\t\tgrpcrouteListerSynced:      grpcrouteInformer.Informer().HasSynced,\n\t\treferenceGrantLister:       referenceGrantInformer.Lister(),\n\t\treferenceGrantListerSynced: referenceGrantInformer.Informer().HasSynced,\n\t}\n\t_, err := gatewayClassInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc: func(obj interface{}) {\n\t\t\tkey, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)\n\t\t\tif err == nil {\n\t\t\t\tc.syncGatewayClass(key)\n\t\t\t}\n\t\t},\n\t\tUpdateFunc: func(oldObj, newObj interface{}) {\n\t\t\tkey, err := cache.DeletionHandlingMetaNamespaceKeyFunc(newObj)\n\t\t\tif err == nil {\n\t\t\t\tc.syncGatewayClass(key)\n\t\t\t}\n\t\t},\n\t\tDeleteFunc: func(obj interface{}) {\n\t\t\tkey, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)\n\t\t\tif err == nil {\n\t\t\t\tc.syncGatewayClass(key)\n\t\t\t}\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = gatewayInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc: func(obj interface{}) {\n\t\t\tgw := obj.(*gatewayv1.Gateway)\n\t\t\tif gw.Spec.GatewayClassName != GWClassName {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tkey, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)\n\t\t\tif err == nil {\n\t\t\t\tc.gatewayqueue.Add(key)\n\t\t\t}\n\t\t},\n\t\tUpdateFunc: func(oldObj, newObj interface{}) {\n\t\t\tgw := newObj.(*gatewayv1.Gateway)\n\t\t\tif gw.Spec.GatewayClassName != GWClassName {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tkey, err := cache.DeletionHandlingMetaNamespaceKeyFunc(newObj)\n\t\t\tif err == nil {\n\t\t\t\tc.gatewayqueue.Add(key)\n\t\t\t}\n\t\t},\n\t\tDeleteFunc: func(obj interface{}) {\n\t\t\tgw := obj.(*gatewayv1.Gateway)\n\t\t\tif gw.Spec.GatewayClassName != GWClassName {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tkey, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)\n\t\t\tif err == nil {\n\t\t\t\tc.gatewayqueue.Add(key)\n\t\t\t}\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = httprouteInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc: func(obj interface{}) {\n\t\t\thttproute := obj.(*gatewayv1.HTTPRoute)\n\t\t\tc.processGateways(httproute.Spec.ParentRefs, httproute.Namespace)\n\t\t},\n\t\tUpdateFunc: func(oldObj, newObj interface{}) {\n\t\t\toldHTTPRoute := oldObj.(*gatewayv1.HTTPRoute)\n\t\t\tnewHTTPRoute := newObj.(*gatewayv1.HTTPRoute)\n\t\t\tc.processGateways(append(oldHTTPRoute.Spec.ParentRefs, newHTTPRoute.Spec.ParentRefs...), newHTTPRoute.Namespace)\n\t\t},\n\t\tDeleteFunc: func(obj interface{}) {\n\t\t\thttproute, ok := obj.(*gatewayv1.HTTPRoute)\n\t\t\tif !ok {\n\t\t\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\t\t\t\tif !ok {\n\t\t\t\t\truntime.HandleError(fmt.Errorf(\"couldn't get object from tombstone %#v\", obj))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\thttproute, ok = tombstone.Obj.(*gatewayv1.HTTPRoute)\n\t\t\t\tif !ok {\n\t\t\t\t\truntime.HandleError(fmt.Errorf(\"tombstone contained object that is not a HTTPRoute: %#v\", obj))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tc.processGateways(httproute.Spec.ParentRefs, httproute.Namespace)\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = grpcrouteInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc: func(obj interface{}) {\n\t\t\tgrpcroute := obj.(*gatewayv1.GRPCRoute)\n\t\t\tc.processGateways(grpcroute.Spec.ParentRefs, grpcroute.Namespace)\n\t\t},\n\t\tUpdateFunc: func(oldObj, newObj interface{}) {\n\t\t\toldGRPCRoute := oldObj.(*gatewayv1.GRPCRoute)\n\t\t\tnewGRPCRoute := newObj.(*gatewayv1.GRPCRoute)\n\t\t\tc.processGateways(append(oldGRPCRoute.Spec.ParentRefs, newGRPCRoute.Spec.ParentRefs...), newGRPCRoute.Namespace)\n\t\t},\n\t\tDeleteFunc: func(obj interface{}) {\n\t\t\tgrpcroute, ok := obj.(*gatewayv1.GRPCRoute)\n\t\t\tif !ok {\n\t\t\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\t\t\t\tif !ok {\n\t\t\t\t\truntime.HandleError(fmt.Errorf(\"couldn't get object from tombstone %#v\", obj))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tgrpcroute, ok = tombstone.Obj.(*gatewayv1.GRPCRoute)\n\t\t\t\tif !ok {\n\t\t\t\t\truntime.HandleError(fmt.Errorf(\"tombstone contained object that is not a GRPCRoute: %#v\", obj))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tc.processGateways(grpcroute.Spec.ParentRefs, grpcroute.Namespace)\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = referenceGrantInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc:    c.processReferenceGrant,\n\t\tUpdateFunc: func(old, new interface{}) { c.processReferenceGrant(new) },\n\t\tDeleteFunc: c.processReferenceGrant,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif config.DefaultConfig.LoadBalancerConnectivity == config.Tunnel {\n\t\tc.tunnelManager = tunnels.NewTunnelManager()\n\t}\n\n\treturn c, nil\n}\n\nfunc (c *Controller) Init(ctx context.Context) error {\n\tdefer runtime.HandleCrashWithContext(ctx)\n\n\tklog.Info(\"Waiting for gateway informer caches to sync\")\n\tif !cache.WaitForNamedCacheSync(controllerName, ctx.Done(),\n\t\tc.gatewayClassListerSynced,\n\t\tc.gatewayListerSynced,\n\t\tc.httprouteListerSynced,\n\t\tc.grpcrouteListerSynced,\n\t\tc.namespaceListerSynced,\n\t\tc.serviceListerSynced,\n\t\tc.secretListerSynced,\n\t\tc.referenceGrantListerSynced,\n\t) {\n\t\treturn fmt.Errorf(\"timed out waiting for caches to sync\")\n\t}\n\n\tkindGwClass := gatewayv1.GatewayClass{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: GWClassName,\n\t\t},\n\t\tSpec: gatewayv1.GatewayClassSpec{\n\t\t\tControllerName: controllerName,\n\t\t\tDescription:    ptr.To(\"cloud-provider-kind gateway API\"),\n\t\t},\n\t}\n\n\t_, err := c.gwClient.GatewayV1().GatewayClasses().Get(ctx, GWClassName, metav1.GetOptions{})\n\tif apierrors.IsNotFound(err) {\n\t\t_, err = c.gwClient.GatewayV1().GatewayClasses().Create(ctx, &kindGwClass, metav1.CreateOptions{})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create cloud-provider-kind GatewayClass: %w\", err)\n\t\t}\n\t} else if err != nil {\n\t\treturn fmt.Errorf(\"failed to get cloud-provider-kind GatewayClass: %w\", err)\n\t}\n\n\t// This is kind/kubeadm specific as it uses kube-system/kube-dns as the nameserver\n\terr = wait.PollUntilContextTimeout(ctx, 100*time.Millisecond, 10*time.Second, true, func(ctx context.Context) (bool, error) {\n\t\tsvc, err := c.serviceLister.Services(metav1.NamespaceSystem).Get(\"kube-dns\")\n\t\tif err != nil {\n\t\t\treturn false, nil\n\t\t}\n\t\tif svc.Spec.ClusterIP == \"\" {\n\t\t\treturn false, nil\n\t\t}\n\t\tc.clusterNameserver = svc.Spec.ClusterIP\n\t\treturn true, nil\n\t})\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get kube-dns service: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (c *Controller) syncGatewayClass(key string) {\n\tstartTime := time.Now()\n\tklog.V(2).Infof(\"Started syncing gatewayclass %q (%v)\", key, time.Since(startTime))\n\tdefer func() {\n\t\tklog.V(2).Infof(\"Finished syncing gatewayclass %q (%v)\", key, time.Since(startTime))\n\t}()\n\n\tgwc, err := c.gatewayClassLister.Get(key)\n\tif err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tklog.V(2).Infof(\"GatewayClass %q has been deleted\", key)\n\t\t}\n\t\treturn\n\t}\n\n\t// We only care about the GatewayClass that matches our controller name.\n\tif gwc.Spec.ControllerName != controllerName {\n\t\treturn\n\t}\n\n\tnewGwc := gwc.DeepCopy()\n\t// Set the \"Accepted\" condition to True and update the observedGeneration.\n\tmeta.SetStatusCondition(&newGwc.Status.Conditions, metav1.Condition{\n\t\tType:               string(gatewayv1.GatewayClassConditionStatusAccepted),\n\t\tStatus:             metav1.ConditionTrue,\n\t\tReason:             string(gatewayv1.GatewayClassReasonAccepted),\n\t\tMessage:            \"GatewayClass is accepted by this controller.\",\n\t\tObservedGeneration: gwc.Generation,\n\t})\n\n\t// Update the status on the API server.\n\tif _, err := c.gwClient.GatewayV1().GatewayClasses().UpdateStatus(context.Background(), newGwc, metav1.UpdateOptions{}); err != nil {\n\t\tklog.Errorf(\"failed to update gatewayclass status: %v\", err)\n\t}\n}\n\nfunc (c *Controller) Run(ctx context.Context) error {\n\tlogger := klog.FromContext(ctx).WithName(\"gateway\")\n\tctx = klog.NewContext(ctx, logger)\n\tdefer runtime.HandleCrashWithContext(ctx)\n\n\tlogger.Info(\"Starting Envoy proxy controller\")\n\tc.xdscache = cachev3.NewSnapshotCache(false, cachev3.IDHash{}, nil)\n\tc.xdsserver = serverv3.NewServer(ctx, c.xdscache, &xdsCallbacks{})\n\n\tvar grpcOptions []grpc.ServerOption\n\tgrpcOptions = append(grpcOptions,\n\t\tgrpc.MaxConcurrentStreams(grpcMaxConcurrentStreams),\n\t\tgrpc.KeepaliveParams(keepalive.ServerParameters{\n\t\t\tTime:    grpcKeepaliveTime,\n\t\t\tTimeout: grpcKeepaliveTimeout,\n\t\t}),\n\t\tgrpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{\n\t\t\tMinTime:             grpcKeepaliveMinTime,\n\t\t\tPermitWithoutStream: true,\n\t\t}),\n\t)\n\tgrpcServer := grpc.NewServer(grpcOptions...)\n\n\tdiscoveryv3.RegisterAggregatedDiscoveryServiceServer(grpcServer, c.xdsserver)\n\tendpointv3.RegisterEndpointDiscoveryServiceServer(grpcServer, c.xdsserver)\n\tclusterv3service.RegisterClusterDiscoveryServiceServer(grpcServer, c.xdsserver)\n\troutev3service.RegisterRouteDiscoveryServiceServer(grpcServer, c.xdsserver)\n\tlistenerv3service.RegisterListenerDiscoveryServiceServer(grpcServer, c.xdsserver)\n\tsecretv3.RegisterSecretDiscoveryServiceServer(grpcServer, c.xdsserver)\n\truntimev3.RegisterRuntimeDiscoveryServiceServer(grpcServer, c.xdsserver)\n\n\taddress, err := GetControlPlaneAddress()\n\tif err != nil {\n\t\treturn err\n\t}\n\tlistener, err := net.Listen(\"tcp\", fmt.Sprintf(\"%s:0\", address))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer listener.Close()\n\n\taddr := listener.Addr()\n\ttcpAddr, ok := addr.(*net.TCPAddr)\n\tif !ok {\n\t\treturn fmt.Errorf(\"could not assert listener address to TCPAddr: %s\", addr.String())\n\t}\n\n\tc.xdsLocalAddress = address\n\tc.xdsLocalPort = tcpAddr.Port\n\tgo func() {\n\t\tlogger.Info(\n\t\t\t\"XDS management server listening\",\n\t\t\t\"address\", c.xdsLocalAddress,\n\t\t\t\"port\", c.xdsLocalPort)\n\t\tif err = grpcServer.Serve(listener); err != nil {\n\t\t\tlogger.Error(err, \"gRPC server error:\")\n\t\t}\n\t\tgrpcServer.Stop()\n\t}()\n\n\tdefer c.gatewayqueue.ShutDown()\n\tlogger.Info(\"Starting Gateway API controller\")\n\n\tfor i := 0; i < workers; i++ {\n\t\tgo wait.UntilWithContext(ctx, c.runGatewayWorker, time.Second)\n\t}\n\n\t<-ctx.Done()\n\tlogger.Info(\"Stopping Gateway API controller\")\n\treturn nil\n}\n\nfunc (c *Controller) processGateways(references []gatewayv1.ParentReference, localNamespace string) {\n\tgatewaysToEnqueue := make(map[string]struct{})\n\tfor _, ref := range references {\n\t\tif (ref.Group != nil && string(*ref.Group) != gatewayv1.GroupName) ||\n\t\t\t(ref.Kind != nil && string(*ref.Kind) != \"Gateway\") {\n\t\t\tcontinue\n\t\t}\n\t\tnamespace := localNamespace\n\t\tif ref.Namespace != nil {\n\t\t\tnamespace = string(*ref.Namespace)\n\t\t}\n\t\tkey := namespace + \"/\" + string(ref.Name)\n\t\tgatewaysToEnqueue[key] = struct{}{}\n\t}\n\n\tfor key := range gatewaysToEnqueue {\n\t\tc.gatewayqueue.Add(key)\n\t}\n}\n\n// processReferenceGrant finds all Gateways that may be affected by a change to a\n// ReferenceGrant and enqueues them for reconciliation. This function handles grants\n// for both cross-namespace BackendRefs (from Routes) and cross-namespace\n// SecretRefs (from Gateways).\nfunc (c *Controller) processReferenceGrant(obj interface{}) {\n\tgrant, ok := obj.(*gatewayv1.ReferenceGrant)\n\tif !ok {\n\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\t\tif !ok {\n\t\t\tklog.Errorf(\"error decoding object, invalid type\")\n\t\t\treturn\n\t\t}\n\t\tgrant, ok = tombstone.Obj.(*gatewayv1.ReferenceGrant)\n\t\tif !ok {\n\t\t\tklog.Errorf(\"error decoding object tombstone, invalid type\")\n\t\t\treturn\n\t\t}\n\t}\n\n\tgatewaysToEnqueue := make(map[string]struct{})\n\t// The ReferenceGrant lives in the namespace of the resource being referenced (the \"To\" side).\n\ttargetNamespace := grant.Namespace\n\n\t// Check for Grants allowing Routes to reference Services\n\tfor _, from := range grant.Spec.From {\n\t\t// As the controller supports more route types, they should be added here.\n\t\tif !CloudProviderSupportedKinds.Has(from.Kind) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check if the grant allows references TO a Service.\n\t\tisServiceGrant := false\n\t\tfor _, to := range grant.Spec.To {\n\t\t\tif to.Kind == \"Service\" {\n\t\t\t\tisServiceGrant = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !isServiceGrant {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find all routes in the \"From\" namespace that could be affected.\n\t\thttpRoutes, err := c.httprouteLister.HTTPRoutes(string(from.Namespace)).List(labels.Everything())\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to list HTTPRoutes in namespace %s: %v\", from.Namespace, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, route := range httpRoutes {\n\t\t\tif routeReferencesBackendInNamespace(route, targetNamespace) {\n\t\t\t\t// This route is affected. Find its parent Gateways and add them to the queue.\n\t\t\t\tfor _, parentRef := range route.Spec.ParentRefs {\n\t\t\t\t\tif (parentRef.Group != nil && string(*parentRef.Group) != gatewayv1.GroupName) ||\n\t\t\t\t\t\t(parentRef.Kind != nil && string(*parentRef.Kind) != \"Gateway\") {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tgwNamespace := route.Namespace\n\t\t\t\t\tif parentRef.Namespace != nil {\n\t\t\t\t\t\tgwNamespace = string(*parentRef.Namespace)\n\t\t\t\t\t}\n\t\t\t\t\tkey := gwNamespace + \"/\" + string(parentRef.Name)\n\t\t\t\t\tgatewaysToEnqueue[key] = struct{}{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check for Grants allowing Gateways to reference Secrets\n\tfor _, from := range grant.Spec.From {\n\t\t// We are looking for grants FROM Gateways.\n\t\tif from.Group != gatewayv1.GroupName || from.Kind != \"Gateway\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check if the grant allows references TO a Secret.\n\t\tisSecretGrant := false\n\t\tfor _, to := range grant.Spec.To {\n\t\t\tif to.Kind == \"Secret\" {\n\t\t\t\tisSecretGrant = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !isSecretGrant {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find all Gateways in the \"From\" namespace that could be affected.\n\t\tgateways, err := c.gatewayLister.Gateways(string(from.Namespace)).List(labels.Everything())\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to list Gateways in namespace %s: %v\", from.Namespace, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, gw := range gateways {\n\t\t\tif gatewayReferencesSecretInNamespace(gw, targetNamespace) {\n\t\t\t\t// This Gateway is affected. Add it to the queue.\n\t\t\t\tkey := gw.Namespace + \"/\" + gw.Name\n\t\t\t\tgatewaysToEnqueue[key] = struct{}{}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Enqueue all unique Gateways that were found to be affected.\n\tfor key := range gatewaysToEnqueue {\n\t\tc.gatewayqueue.Add(key)\n\t}\n}\n\n// routeReferencesBackendInNamespace is a helper to check if an HTTPRoute has a backendRef\n// pointing to the specified namespace.\nfunc routeReferencesBackendInNamespace(route *gatewayv1.HTTPRoute, namespace string) bool {\n\tfor _, rule := range route.Spec.Rules {\n\t\tfor _, backendRef := range rule.BackendRefs {\n\t\t\tbackendNamespace := route.Namespace\n\t\t\tif backendRef.Namespace != nil {\n\t\t\t\tbackendNamespace = string(*backendRef.Namespace)\n\t\t\t}\n\t\t\tif backendNamespace == namespace {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// gatewayReferencesSecretInNamespace is a helper to check if a Gateway has a certificateRef\n// pointing to a Secret in the specified namespace.\nfunc gatewayReferencesSecretInNamespace(gateway *gatewayv1.Gateway, namespace string) bool {\n\tfor _, listener := range gateway.Spec.Listeners {\n\t\tif listener.TLS == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, certRef := range listener.TLS.CertificateRefs {\n\t\t\t// We only care about references to Secrets.\n\t\t\tif (certRef.Group != nil && *certRef.Group != \"\") || (certRef.Kind != nil && *certRef.Kind != \"Secret\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsecretNamespace := gateway.Namespace\n\t\t\tif certRef.Namespace != nil {\n\t\t\t\tsecretNamespace = string(*certRef.Namespace)\n\t\t\t}\n\t\t\tif secretNamespace == namespace {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Controller) runGatewayWorker(ctx context.Context) {\n\tfor c.processNextGatewayItem(ctx) {\n\t}\n}\n\nfunc (c *Controller) processNextGatewayItem(ctx context.Context) bool {\n\tkey, quit := c.gatewayqueue.Get()\n\tif quit {\n\t\treturn false\n\t}\n\tdefer c.gatewayqueue.Done(key)\n\n\terr := c.syncGateway(ctx, key)\n\tc.handleGatewayErr(err, key)\n\treturn true\n}\n\nfunc (c *Controller) handleGatewayErr(err error, key string) {\n\tif err == nil {\n\t\tc.gatewayqueue.Forget(key)\n\t\treturn\n\t}\n\n\tif c.gatewayqueue.NumRequeues(key) < maxRetries {\n\t\tklog.Infof(\"Error syncing Gateway %v: %v\", key, err)\n\t\tc.gatewayqueue.AddRateLimited(key)\n\t\treturn\n\t}\n\n\tc.gatewayqueue.Forget(key)\n\truntime.HandleError(err)\n\tklog.Infof(\"Dropping Gateway %q out of the queue: %v\", key, err)\n}\n\nfunc GetControlPlaneAddress() (string, error) {\n\tinterfaces, err := net.Interfaces()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tsort.Slice(interfaces, func(i, j int) bool {\n\t\tnameI := interfaces[i].Name\n\t\tnameJ := interfaces[j].Name\n\n\t\tif nameI == \"docker0\" {\n\t\t\treturn true\n\t\t}\n\t\tif nameJ == \"docker0\" {\n\t\t\treturn false\n\t\t}\n\n\t\tif nameI == \"eth0\" {\n\t\t\treturn nameJ != \"docker0\"\n\t\t}\n\t\tif nameJ == \"eth0\" {\n\t\t\treturn false\n\t\t}\n\n\t\treturn nameI < nameJ\n\t})\n\n\tfor _, iface := range interfaces {\n\t\tif iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\taddrs, err := iface.Addrs()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, addr := range addrs {\n\t\t\tipNet, ok := addr.(*net.IPNet)\n\t\t\tif ok && ipNet.IP.To4() != nil && !ipNet.IP.IsLinkLocalUnicast() && !ipNet.IP.IsLoopback() {\n\t\t\t\treturn ipNet.IP.String(), nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"no suitable global unicast IPv4 address found on any active non-loopback interface\")\n}\n\nfunc (c *Controller) UpdateXDSServer(ctx context.Context, nodeid string, resources map[resourcev3.Type][]envoyproxytypes.Resource) error {\n\tc.xdsVersion.Add(1)\n\n\tsnapshot, err := cachev3.NewSnapshot(fmt.Sprintf(\"%d\", c.xdsVersion.Load()), resources)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create new snapshot cache: %v\", err)\n\n\t}\n\n\tif err := c.xdscache.SetSnapshot(ctx, nodeid, snapshot); err != nil {\n\t\treturn fmt.Errorf(\"failed to update resource snapshot in management server: %v\", err)\n\t}\n\tlogger := klog.FromContext(ctx).WithValues(\"nodeID\", nodeid)\n\tlogger.V(4).Info(\"Updated snapshot cache with resource snapshot...\")\n\treturn nil\n}\n\nvar _ serverv3.Callbacks = &xdsCallbacks{}\n\ntype xdsCallbacks struct{}\n\nfunc (cb *xdsCallbacks) OnStreamOpen(ctx context.Context, id int64, typ string) error {\n\tklog.V(2).Infof(\"xDS stream %d opened for type %s\", id, typ)\n\treturn nil\n}\nfunc (cb *xdsCallbacks) OnStreamClosed(id int64, node *corev3.Node) {\n\tnodeID := \"unknown\"\n\tif node != nil {\n\t\tnodeID = node.GetId()\n\t}\n\tklog.V(2).Infof(\"xDS stream %d closed for node %s\", id, nodeID)\n}\nfunc (cb *xdsCallbacks) OnStreamRequest(id int64, req *discoveryv3.DiscoveryRequest) error {\n\tklog.V(5).Infof(\"xDS stream %d received request for type %s from node %s\", id, req.TypeUrl, req.Node.GetId())\n\treturn nil\n}\nfunc (cb *xdsCallbacks) OnStreamResponse(ctx context.Context, id int64, req *discoveryv3.DiscoveryRequest, resp *discoveryv3.DiscoveryResponse) {\n\tklog.V(5).Infof(\"xDS stream %d sent response for type %s to node %s\", id, resp.TypeUrl, req.Node.GetId())\n}\nfunc (cb *xdsCallbacks) OnFetchRequest(ctx context.Context, req *discoveryv3.DiscoveryRequest) error {\n\tklog.V(5).Infof(\"xDS fetch request received for type %s from node %s\", req.TypeUrl, req.Node.GetId())\n\treturn nil\n}\nfunc (cb *xdsCallbacks) OnFetchResponse(req *discoveryv3.DiscoveryRequest, resp *discoveryv3.DiscoveryResponse) {\n\tklog.V(5).Infof(\"xDS fetch response sent for type %s to node %s\", resp.TypeUrl, req.Node.GetId())\n}\nfunc (cb *xdsCallbacks) OnStreamDeltaRequest(id int64, req *discoveryv3.DeltaDiscoveryRequest) error {\n\treturn nil\n}\nfunc (cb *xdsCallbacks) OnStreamDeltaResponse(id int64, req *discoveryv3.DeltaDiscoveryRequest, resp *discoveryv3.DeltaDiscoveryResponse) {\n}\nfunc (cb *xdsCallbacks) OnDeltaStreamClosed(int64, *corev3.Node) {}\nfunc (cb *xdsCallbacks) OnDeltaStreamOpen(context.Context, int64, string) error {\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/gateway/controller_test.go",
    "content": "package gateway\n"
  },
  {
    "path": "pkg/gateway/crd_manager.go",
    "content": "package gateway\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"path\"\n\t\"strings\"\n\n\t\"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/util/yaml\"\n\t\"k8s.io/client-go/dynamic\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/klog/v2\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n)\n\n//go:embed crds/standard/*.yaml crds/experimental/*.yaml\nvar crdFS embed.FS\n\nconst (\n\tcrdsDir = \"crds\" // Base directory within the embedded FS\n\t// use constants to avoid the dependency on apiextensions\n\tcrdKind       = \"CustomResourceDefinition\"\n\tcrdResource   = \"customresourcedefinitions\"\n\tcrdGroup      = \"apiextensions.k8s.io\"\n\tcrdVersion    = \"v1\"\n\tcrdAPIVersion = \"apiextensions.k8s.io/v1\"\n)\n\n// CRDManager handles the installation of Gateway API CRDs.\ntype CRDManager struct {\n\tdynamicClient dynamic.Interface\n}\n\n// NewCRDManager creates a new CRDManager instance.\n// It attempts to load in-cluster config first, then falls back to kubeconfig.\nfunc NewCRDManager(config *rest.Config) (*CRDManager, error) {\n\tdynamicClient, err := dynamic.NewForConfig(config)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create dynamic client: %w\", err)\n\t}\n\n\treturn &CRDManager{\n\t\tdynamicClient: dynamicClient,\n\t}, nil\n}\n\n// InstallCRDs reads CRDs from the embedded filesystem and applies them to the cluster.\nfunc (m *CRDManager) InstallCRDs(ctx context.Context, channelDir config.GatewayReleaseChannel) error {\n\tcrdGVR := schema.GroupVersionResource{\n\t\tGroup:    crdGroup,\n\t\tVersion:  crdVersion,\n\t\tResource: crdResource,\n\t}\n\n\t// embed.FS always uses Unix path names\n\ttargetDir := path.Join(crdsDir, string(channelDir))\n\n\tklog.Infof(\"Walking embedded directory for channel %q: %s\", channelDir, targetDir)\n\terr := fs.WalkDir(crdFS, targetDir, func(path string, d fs.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error walking embedded fs at %q: %w\", path, err)\n\t\t}\n\n\t\t// Skip directories\n\t\tif d.IsDir() {\n\t\t\t// Skip the root directory itself, only process files within it\n\t\t\tif path == targetDir {\n\t\t\t\tklog.V(4).Infof(\"Entering directory: %s\", path)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tklog.V(4).Infof(\"Skipping directory: %s\", path)\n\t\t\treturn nil // Continue walking\n\t\t}\n\n\t\t// Skip the kustomize files\n\t\tif strings.HasSuffix(path, \"kustomization.yaml\") {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Process only YAML files\n\t\tif !strings.HasSuffix(path, \".yaml\") && !strings.HasSuffix(path, \".yml\") {\n\t\t\tklog.V(4).Infof(\"Skipping non-yaml file: %s\", path)\n\t\t\treturn nil\n\t\t}\n\n\t\tklog.Infof(\"Processing embedded CRD file: %s\", path)\n\t\tfile, err := crdFS.Open(path)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to open embedded file %q: %w\", path, err)\n\t\t}\n\t\tdefer file.Close()\n\n\t\t// Use a YAML decoder to handle multi-document files\n\t\tdecoder := yaml.NewYAMLOrJSONDecoder(file, 4096)\n\t\tfor {\n\t\t\tobj := &unstructured.Unstructured{}\n\t\t\tif err := decoder.Decode(obj); err != nil {\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\tbreak // End of file\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"failed to decode YAML document from %q: %w\", path, err)\n\t\t\t}\n\n\t\t\t// Basic validation\n\t\t\tif obj.GetKind() != crdKind || obj.GetAPIVersion() != crdAPIVersion {\n\t\t\t\tklog.Warningf(\"Skipping object in %q with unexpected kind/apiVersion: %s/%s\", path, obj.GetAPIVersion(), obj.GetKind())\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcrdName := obj.GetName()\n\t\t\tklog.Infof(\"Attempting to create CRD: %s\", crdName)\n\t\t\t_, createErr := m.dynamicClient.Resource(crdGVR).Create(ctx, obj, metav1.CreateOptions{})\n\t\t\tif createErr != nil {\n\t\t\t\tif errors.IsAlreadyExists(createErr) {\n\t\t\t\t\tklog.Infof(\"CRD %q already exists, skipping creation.\", crdName)\n\t\t\t\t\t// TODO: Consider updating/patching if needed, but for CRDs, create-if-not-exists is often sufficient.\n\t\t\t\t} else {\n\t\t\t\t\treturn fmt.Errorf(\"failed to create CRD %q from file %q: %w\", crdName, path, createErr)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tklog.Infof(\"Successfully created CRD: %s\", crdName)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error processing embedded CRDs from %s: %w\", targetDir, err)\n\t}\n\n\tklog.Info(\"Finished processing embedded CRDs.\")\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/gateway/crd_manager_test.go",
    "content": "package gateway\n\nimport (\n\t\"testing\"\n\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/client-go/dynamic/fake\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n)\n\nfunc TestYAMLFilesApply(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tchannel config.GatewayReleaseChannel\n\t}{\n\t\t{\n\t\tname: \"Stable release channel\",\n\t\tchannel: config.Standard,\n\t\t},\n\n\t\t{\n\t\t\tname: \"Experimental release channel\",\n\t\t\tchannel: config.Experimental,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tmanager := CRDManager {\n\t\t\t\tdynamicClient: fake.NewSimpleDynamicClient(runtime.NewScheme()),\n\n\t\t\t}\n\n\t\t\tif err := manager.InstallCRDs(t.Context(), tt.channel); err != nil {\n\t\t\t\tt.Fatalf(\"couldn't install CRDs: %v\", err)\n\n\t\t\t}\n\t\t})\n\n\t}\n}\n\n"
  },
  {
    "path": "pkg/gateway/crds/README.md",
    "content": "# Gateway CRDs\n\nThis folder is updated with `hack/download-gateway-crds.sh` script to obtain\nthe lastest CRDs from https://github.com/kubernetes-sigs/gateway-api\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  labels:\n    gateway.networking.k8s.io/policy: Direct\n  name: backendtlspolicies.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: BackendTLSPolicy\n    listKind: BackendTLSPolicyList\n    plural: backendtlspolicies\n    shortNames:\n    - btlspolicy\n    singular: backendtlspolicy\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          BackendTLSPolicy provides a way to configure how a Gateway\n          connects to a Backend via TLS.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of BackendTLSPolicy.\n            properties:\n              options:\n                additionalProperties:\n                  description: |-\n                    AnnotationValue is the value of an annotation in Gateway API. This is used\n                    for validation of maps such as TLS options. This roughly matches Kubernetes\n                    annotation validation, although the length validation in that case is based\n                    on the entire size of the annotations struct.\n                  maxLength: 4096\n                  minLength: 0\n                  type: string\n                description: |-\n                  Options are a list of key/value pairs to enable extended TLS\n                  configuration for each implementation. For example, configuring the\n                  minimum TLS version or supported cipher suites.\n\n                  A set of common keys MAY be defined by the API in the future. To avoid\n                  any ambiguity, implementation-specific definitions MUST use\n                  domain-prefixed names, such as `example.com/my-custom-option`.\n                  Un-prefixed names are reserved for key names defined by Gateway API.\n\n                  Support: Implementation-specific\n                maxProperties: 16\n                type: object\n              targetRefs:\n                description: |-\n                  TargetRefs identifies an API object to apply the policy to.\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n\n                  TargetRefs must be _distinct_. This means either that:\n\n                  * They select different targets. If this is the case, then targetRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, and `name` must\n                    be unique across all targetRef entries in the BackendTLSPolicy.\n                  * They select different sectionNames in the same target.\n\n                  When more than one BackendTLSPolicy selects the same target and\n                  sectionName, implementations MUST determine precedence using the\n                  following criteria, continuing on ties:\n\n                  * The older policy by creation timestamp takes precedence. For\n                    example, a policy with a creation timestamp of \"2021-07-15\n                    01:02:03\" MUST be given precedence over a policy with a\n                    creation timestamp of \"2021-07-15 01:02:04\".\n                  * The policy appearing first in alphabetical order by {namespace}/{name}.\n                    For example, a policy named `foo/bar` is given precedence over a\n                    policy named `foo/baz`.\n\n                  For any BackendTLSPolicy that does not take precedence, the\n                  implementation MUST ensure the `Accepted` Condition is set to\n                  `status: False`, with Reason `Conflicted`.\n\n                  Implementations SHOULD NOT support more than one targetRef at this\n                  time. Although the API technically allows for this, the current guidance\n                  for conflict resolution and status handling is lacking. Until that can be\n                  clarified in a future release, the safest approach is to support a single\n                  targetRef.\n\n                  Support Levels:\n\n                  * Extended: Kubernetes Service referenced by HTTPRoute backendRefs.\n\n                  * Implementation-Specific: Services not connected via HTTPRoute, and any\n                    other kind of backend. Implementations MAY use BackendTLSPolicy for:\n                    - Services not referenced by any Route (e.g., infrastructure services)\n                    - Gateway feature backends (e.g., ExternalAuth, rate-limiting services)\n                    - Service mesh workload-to-service communication\n                    - Other resource types beyond Service\n\n                  Implementations SHOULD aim to ensure that BackendTLSPolicy behavior is consistent,\n                  even outside of the extended HTTPRoute -(backendRef) -> Service path.\n                  They SHOULD clearly document how BackendTLSPolicy is interpreted in these\n                  scenarios, including:\n                    - Which resources beyond Service are supported\n                    - How the policy is discovered and applied\n                    - Any implementation-specific semantics or restrictions\n\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n                items:\n                  description: |-\n                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\n                    direct policy to. This should be used as part of Policy resources that can\n                    target single resources. For more information on how this policy attachment\n                    mode works, and a sample Policy resource, refer to the policy attachment\n                    documentation for Gateway API.\n\n                    Note: This should only be used for direct policy attachment when references\n                    to SectionName are actually needed. In all other cases,\n                    LocalPolicyTargetReference should be used.\n                  properties:\n                    group:\n                      description: Group is the group of the target resource.\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: Kind is kind of the target resource.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: Name is the name of the target resource.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. When\n                        unspecified, this targetRef targets the entire resource. In the following\n                        resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name\n                        * HTTPRoute: HTTPRouteRule name\n                        * Service: Port name\n\n                        If a SectionName is specified, but does not exist on the targeted object,\n                        the Policy must fail to attach, and the policy implementation should record\n                        a `ResolvedRefs` or similar Condition in the Policy's status.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - name\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when targetRefs includes\n                    2 or more references to the same target\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName\n                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))\n                    : true))'\n                - message: sectionName must be unique when targetRefs includes 2 or\n                    more references to the same target\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||\n                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              validation:\n                description: Validation contains backend TLS validation configuration.\n                properties:\n                  caCertificateRefs:\n                    description: |-\n                      CACertificateRefs contains one or more references to Kubernetes objects that\n                      contain a PEM-encoded TLS CA certificate bundle, which is used to\n                      validate a TLS handshake between the Gateway and backend Pod.\n\n                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be\n                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,\n                      not both. If CACertificateRefs is empty or unspecified, the configuration for\n                      WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\n                      A CACertificateRef is invalid if:\n\n                      * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key\n                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`\n                        and the Message of the Condition must indicate which reference is invalid and why.\n\n                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason\n                        must be set to `InvalidKind` and the Message of the Condition must explain which\n                        kind of resource is unknown or unsupported.\n\n                      * It refers to a resource in another namespace. This may change in future\n                        spec updates.\n\n                      Implementations MAY choose to perform further validation of the certificate\n                      content (e.g., checking expiry or enforcing specific formats). In such cases,\n                      an implementation-specific Reason and Message must be set for the invalid reference.\n\n                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on\n                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message\n                      that indicate the cause of the error. Connections using an invalid\n                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error\n                      response. If ALL CACertificateRefs are invalid, the implementation MUST also\n                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to\n                      `status: False`, with a Reason `NoValidCACertificate`.\n\n                      A single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support.\n                      Implementations MAY choose to support attaching multiple certificates to\n                      a backend, but this behavior is implementation-specific.\n\n                      Support: Core - An optional single reference to a Kubernetes ConfigMap,\n                      with the CA certificate in a key named `ca.crt`.\n\n                      Support: Implementation-specific - More than one reference, other kinds\n                      of resources, or a single reference that includes multiple certificates.\n                    items:\n                      description: |-\n                        LocalObjectReference identifies an API object within the namespace of the\n                        referrer.\n                        The API object must be valid in the cluster; the Group and Kind must\n                        be registered in the cluster for this reference to be valid.\n\n                        References to objects with invalid Group and Kind are not valid, and must\n                        be rejected by the implementation, with appropriate Conditions set\n                        on the containing object.\n                      properties:\n                        group:\n                          description: |-\n                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                            When unspecified or empty string, core API group is inferred.\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          description: Kind is kind of the referent. For example \"HTTPRoute\"\n                            or \"Service\".\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: Name is the name of the referent.\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                      required:\n                      - group\n                      - kind\n                      - name\n                      type: object\n                    maxItems: 8\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  hostname:\n                    description: |-\n                      Hostname is used for two purposes in the connection between Gateways and\n                      backends:\n\n                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).\n                      2. Hostname MUST be used for authentication and MUST match the certificate\n                         served by the matching backend, unless SubjectAltNames is specified.\n                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection\n                         but MUST NOT be used for authentication. If you want to use the value\n                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.\n\n                      Support: Core\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  subjectAltNames:\n                    description: |-\n                      SubjectAltNames contains one or more Subject Alternative Names.\n                      When specified the certificate served from the backend MUST\n                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\n                      Support: Extended\n                    items:\n                      description: SubjectAltName represents Subject Alternative Name.\n                      properties:\n                        hostname:\n                          description: |-\n                            Hostname contains Subject Alternative Name specified in DNS name format.\n                            Required when Type is set to Hostname, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        type:\n                          description: |-\n                            Type determines the format of the Subject Alternative Name. Always required.\n\n                            Support: Core\n                          enum:\n                          - Hostname\n                          - URI\n                          type: string\n                        uri:\n                          description: |-\n                            URI contains Subject Alternative Name specified in a full URI format.\n                            It MUST include both a scheme (e.g., \"http\" or \"ftp\") and a scheme-specific-part.\n                            Common values include SPIFFE IDs like \"spiffe://mycluster.example.com/ns/myns/sa/svc1sa\".\n                            Required when Type is set to URI, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\\?([^#]*))?(#(.*))?\n                          type: string\n                      required:\n                      - type\n                      type: object\n                      x-kubernetes-validations:\n                      - message: SubjectAltName element must contain Hostname, if\n                          Type is set to Hostname\n                        rule: '!(self.type == \"Hostname\" && (!has(self.hostname) ||\n                          self.hostname == \"\"))'\n                      - message: SubjectAltName element must not contain Hostname,\n                          if Type is not set to Hostname\n                        rule: '!(self.type != \"Hostname\" && has(self.hostname) &&\n                          self.hostname != \"\")'\n                      - message: SubjectAltName element must contain URI, if Type\n                          is set to URI\n                        rule: '!(self.type == \"URI\" && (!has(self.uri) || self.uri\n                          == \"\"))'\n                      - message: SubjectAltName element must not contain URI, if Type\n                          is not set to URI\n                        rule: '!(self.type != \"URI\" && has(self.uri) && self.uri !=\n                          \"\")'\n                    maxItems: 5\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  wellKnownCACertificates:\n                    description: |-\n                      WellKnownCACertificates specifies whether a well-known set of CA certificates\n                      may be used in the TLS handshake between the gateway and backend pod.\n\n                      If WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\n                      must be specified with at least one entry for a valid configuration. Only one of\n                      CACertificateRefs or WellKnownCACertificates may be specified, not both.\n                      If an implementation does not support the WellKnownCACertificates field, or\n                      the supplied value is not recognized, the implementation MUST ensure the\n                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\n                      a Reason `Invalid`.\n\n                      Valid values include:\n                      * \"System\" - indicates that well-known system CA certificates should be used.\n\n                      Implementations MAY define their own sets of CA certificates. Such definitions\n                      MUST use an implementation-specific, prefixed name, such as\n                      `mycompany.com/my-custom-ca-certifcates`.\n\n                      Support: Implementation-specific\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$\n                    type: string\n                required:\n                - hostname\n                type: object\n                x-kubernetes-validations:\n                - message: must not contain both CACertificateRefs and WellKnownCACertificates\n                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")'\n                - message: must specify either CACertificateRefs or WellKnownCACertificates\n                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")\n            required:\n            - targetRefs\n            - validation\n            type: object\n          status:\n            description: Status defines the current state of BackendTLSPolicy.\n            properties:\n              ancestors:\n                description: |-\n                  Ancestors is a list of ancestor resources (usually Gateways) that are\n                  associated with the policy, and the status of the policy with respect to\n                  each ancestor. When this policy attaches to a parent, the controller that\n                  manages the parent and the ancestors MUST add an entry to this list when\n                  the controller first sees the policy and SHOULD update the entry as\n                  appropriate when the relevant ancestor is modified.\n\n                  Note that choosing the relevant ancestor is left to the Policy designers;\n                  an important part of Policy design is designing the right object level at\n                  which to namespace this status.\n\n                  Note also that implementations MUST ONLY populate ancestor status for\n                  the Ancestor resources they are responsible for. Implementations MUST\n                  use the ControllerName field to uniquely identify the entries in this list\n                  that they are responsible for.\n\n                  Note that to achieve this, the list of PolicyAncestorStatus structs\n                  MUST be treated as a map with a composite key, made up of the AncestorRef\n                  and ControllerName fields combined.\n\n                  A maximum of 16 ancestors will be represented in this list. An empty list\n                  means the Policy is not relevant for any ancestors.\n\n                  If this slice is full, implementations MUST NOT add further entries.\n                  Instead they MUST consider the policy unimplementable and signal that\n                  on any related resources such as the ancestor that would be referenced\n                  here. For example, if this list was full on BackendTLSPolicy, no\n                  additional Gateways would be able to reference the Service targeted by\n                  the BackendTLSPolicy.\n                items:\n                  description: |-\n                    PolicyAncestorStatus describes the status of a route with respect to an\n                    associated Ancestor.\n\n                    Ancestors refer to objects that are either the Target of a policy or above it\n                    in terms of object hierarchy. For example, if a policy targets a Service, the\n                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\n                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\n                    useful object to place Policy status on, so we recommend that implementations\n                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers\n                    have a _very_ good reason otherwise.\n\n                    In the context of policy attachment, the Ancestor is used to distinguish which\n                    resource results in a distinct application of this policy. For example, if a policy\n                    targets a Service, it may have a distinct result per attached Gateway.\n\n                    Policies targeting the same resource may have different effects depending on the\n                    ancestors of those resources. For example, different Gateways targeting the same\n                    Service may have different capabilities, especially if they have different underlying\n                    implementations.\n\n                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is\n                    used as a backend in a HTTPRoute that is itself attached to a Gateway.\n                    In this case, the relevant object for status is the Gateway, and that is the\n                    ancestor object referred to in this status.\n\n                    Note that a parent is also an ancestor, so for objects where the parent is the\n                    relevant object for status, this struct SHOULD still be used.\n\n                    This struct is intended to be used in a slice that's effectively a map,\n                    with a composite key made up of the AncestorRef and the ControllerName.\n                  properties:\n                    ancestorRef:\n                      description: |-\n                        AncestorRef corresponds with a ParentRef in the spec that this\n                        PolicyAncestorStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    conditions:\n                      description: Conditions describes the status of the Policy with\n                        respect to the given Ancestor.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                  required:\n                  - ancestorRef\n                  - conditions\n                  - controllerName\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - ancestors\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - deprecated: true\n    deprecationWarning: The v1alpha3 version of BackendTLSPolicy has been deprecated\n      and will be removed in a future release of the API. Please upgrade to v1.\n    name: v1alpha3\n    schema:\n      openAPIV3Schema:\n        description: |-\n          BackendTLSPolicy provides a way to configure how a Gateway\n          connects to a Backend via TLS.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of BackendTLSPolicy.\n            properties:\n              options:\n                additionalProperties:\n                  description: |-\n                    AnnotationValue is the value of an annotation in Gateway API. This is used\n                    for validation of maps such as TLS options. This roughly matches Kubernetes\n                    annotation validation, although the length validation in that case is based\n                    on the entire size of the annotations struct.\n                  maxLength: 4096\n                  minLength: 0\n                  type: string\n                description: |-\n                  Options are a list of key/value pairs to enable extended TLS\n                  configuration for each implementation. For example, configuring the\n                  minimum TLS version or supported cipher suites.\n\n                  A set of common keys MAY be defined by the API in the future. To avoid\n                  any ambiguity, implementation-specific definitions MUST use\n                  domain-prefixed names, such as `example.com/my-custom-option`.\n                  Un-prefixed names are reserved for key names defined by Gateway API.\n\n                  Support: Implementation-specific\n                maxProperties: 16\n                type: object\n              targetRefs:\n                description: |-\n                  TargetRefs identifies an API object to apply the policy to.\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n\n                  TargetRefs must be _distinct_. This means either that:\n\n                  * They select different targets. If this is the case, then targetRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, and `name` must\n                    be unique across all targetRef entries in the BackendTLSPolicy.\n                  * They select different sectionNames in the same target.\n\n                  When more than one BackendTLSPolicy selects the same target and\n                  sectionName, implementations MUST determine precedence using the\n                  following criteria, continuing on ties:\n\n                  * The older policy by creation timestamp takes precedence. For\n                    example, a policy with a creation timestamp of \"2021-07-15\n                    01:02:03\" MUST be given precedence over a policy with a\n                    creation timestamp of \"2021-07-15 01:02:04\".\n                  * The policy appearing first in alphabetical order by {namespace}/{name}.\n                    For example, a policy named `foo/bar` is given precedence over a\n                    policy named `foo/baz`.\n\n                  For any BackendTLSPolicy that does not take precedence, the\n                  implementation MUST ensure the `Accepted` Condition is set to\n                  `status: False`, with Reason `Conflicted`.\n\n                  Implementations SHOULD NOT support more than one targetRef at this\n                  time. Although the API technically allows for this, the current guidance\n                  for conflict resolution and status handling is lacking. Until that can be\n                  clarified in a future release, the safest approach is to support a single\n                  targetRef.\n\n                  Support Levels:\n\n                  * Extended: Kubernetes Service referenced by HTTPRoute backendRefs.\n\n                  * Implementation-Specific: Services not connected via HTTPRoute, and any\n                    other kind of backend. Implementations MAY use BackendTLSPolicy for:\n                    - Services not referenced by any Route (e.g., infrastructure services)\n                    - Gateway feature backends (e.g., ExternalAuth, rate-limiting services)\n                    - Service mesh workload-to-service communication\n                    - Other resource types beyond Service\n\n                  Implementations SHOULD aim to ensure that BackendTLSPolicy behavior is consistent,\n                  even outside of the extended HTTPRoute -(backendRef) -> Service path.\n                  They SHOULD clearly document how BackendTLSPolicy is interpreted in these\n                  scenarios, including:\n                    - Which resources beyond Service are supported\n                    - How the policy is discovered and applied\n                    - Any implementation-specific semantics or restrictions\n\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n                items:\n                  description: |-\n                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\n                    direct policy to. This should be used as part of Policy resources that can\n                    target single resources. For more information on how this policy attachment\n                    mode works, and a sample Policy resource, refer to the policy attachment\n                    documentation for Gateway API.\n\n                    Note: This should only be used for direct policy attachment when references\n                    to SectionName are actually needed. In all other cases,\n                    LocalPolicyTargetReference should be used.\n                  properties:\n                    group:\n                      description: Group is the group of the target resource.\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: Kind is kind of the target resource.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: Name is the name of the target resource.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. When\n                        unspecified, this targetRef targets the entire resource. In the following\n                        resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name\n                        * HTTPRoute: HTTPRouteRule name\n                        * Service: Port name\n\n                        If a SectionName is specified, but does not exist on the targeted object,\n                        the Policy must fail to attach, and the policy implementation should record\n                        a `ResolvedRefs` or similar Condition in the Policy's status.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - name\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when targetRefs includes\n                    2 or more references to the same target\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName\n                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))\n                    : true))'\n                - message: sectionName must be unique when targetRefs includes 2 or\n                    more references to the same target\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||\n                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              validation:\n                description: Validation contains backend TLS validation configuration.\n                properties:\n                  caCertificateRefs:\n                    description: |-\n                      CACertificateRefs contains one or more references to Kubernetes objects that\n                      contain a PEM-encoded TLS CA certificate bundle, which is used to\n                      validate a TLS handshake between the Gateway and backend Pod.\n\n                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be\n                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,\n                      not both. If CACertificateRefs is empty or unspecified, the configuration for\n                      WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\n                      A CACertificateRef is invalid if:\n\n                      * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key\n                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`\n                        and the Message of the Condition must indicate which reference is invalid and why.\n\n                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason\n                        must be set to `InvalidKind` and the Message of the Condition must explain which\n                        kind of resource is unknown or unsupported.\n\n                      * It refers to a resource in another namespace. This may change in future\n                        spec updates.\n\n                      Implementations MAY choose to perform further validation of the certificate\n                      content (e.g., checking expiry or enforcing specific formats). In such cases,\n                      an implementation-specific Reason and Message must be set for the invalid reference.\n\n                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on\n                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message\n                      that indicate the cause of the error. Connections using an invalid\n                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error\n                      response. If ALL CACertificateRefs are invalid, the implementation MUST also\n                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to\n                      `status: False`, with a Reason `NoValidCACertificate`.\n\n                      A single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support.\n                      Implementations MAY choose to support attaching multiple certificates to\n                      a backend, but this behavior is implementation-specific.\n\n                      Support: Core - An optional single reference to a Kubernetes ConfigMap,\n                      with the CA certificate in a key named `ca.crt`.\n\n                      Support: Implementation-specific - More than one reference, other kinds\n                      of resources, or a single reference that includes multiple certificates.\n                    items:\n                      description: |-\n                        LocalObjectReference identifies an API object within the namespace of the\n                        referrer.\n                        The API object must be valid in the cluster; the Group and Kind must\n                        be registered in the cluster for this reference to be valid.\n\n                        References to objects with invalid Group and Kind are not valid, and must\n                        be rejected by the implementation, with appropriate Conditions set\n                        on the containing object.\n                      properties:\n                        group:\n                          description: |-\n                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                            When unspecified or empty string, core API group is inferred.\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          description: Kind is kind of the referent. For example \"HTTPRoute\"\n                            or \"Service\".\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: Name is the name of the referent.\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                      required:\n                      - group\n                      - kind\n                      - name\n                      type: object\n                    maxItems: 8\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  hostname:\n                    description: |-\n                      Hostname is used for two purposes in the connection between Gateways and\n                      backends:\n\n                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).\n                      2. Hostname MUST be used for authentication and MUST match the certificate\n                         served by the matching backend, unless SubjectAltNames is specified.\n                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection\n                         but MUST NOT be used for authentication. If you want to use the value\n                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.\n\n                      Support: Core\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  subjectAltNames:\n                    description: |-\n                      SubjectAltNames contains one or more Subject Alternative Names.\n                      When specified the certificate served from the backend MUST\n                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\n                      Support: Extended\n                    items:\n                      description: SubjectAltName represents Subject Alternative Name.\n                      properties:\n                        hostname:\n                          description: |-\n                            Hostname contains Subject Alternative Name specified in DNS name format.\n                            Required when Type is set to Hostname, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        type:\n                          description: |-\n                            Type determines the format of the Subject Alternative Name. Always required.\n\n                            Support: Core\n                          enum:\n                          - Hostname\n                          - URI\n                          type: string\n                        uri:\n                          description: |-\n                            URI contains Subject Alternative Name specified in a full URI format.\n                            It MUST include both a scheme (e.g., \"http\" or \"ftp\") and a scheme-specific-part.\n                            Common values include SPIFFE IDs like \"spiffe://mycluster.example.com/ns/myns/sa/svc1sa\".\n                            Required when Type is set to URI, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\\?([^#]*))?(#(.*))?\n                          type: string\n                      required:\n                      - type\n                      type: object\n                      x-kubernetes-validations:\n                      - message: SubjectAltName element must contain Hostname, if\n                          Type is set to Hostname\n                        rule: '!(self.type == \"Hostname\" && (!has(self.hostname) ||\n                          self.hostname == \"\"))'\n                      - message: SubjectAltName element must not contain Hostname,\n                          if Type is not set to Hostname\n                        rule: '!(self.type != \"Hostname\" && has(self.hostname) &&\n                          self.hostname != \"\")'\n                      - message: SubjectAltName element must contain URI, if Type\n                          is set to URI\n                        rule: '!(self.type == \"URI\" && (!has(self.uri) || self.uri\n                          == \"\"))'\n                      - message: SubjectAltName element must not contain URI, if Type\n                          is not set to URI\n                        rule: '!(self.type != \"URI\" && has(self.uri) && self.uri !=\n                          \"\")'\n                    maxItems: 5\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  wellKnownCACertificates:\n                    description: |-\n                      WellKnownCACertificates specifies whether a well-known set of CA certificates\n                      may be used in the TLS handshake between the gateway and backend pod.\n\n                      If WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\n                      must be specified with at least one entry for a valid configuration. Only one of\n                      CACertificateRefs or WellKnownCACertificates may be specified, not both.\n                      If an implementation does not support the WellKnownCACertificates field, or\n                      the supplied value is not recognized, the implementation MUST ensure the\n                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\n                      a Reason `Invalid`.\n\n                      Valid values include:\n                      * \"System\" - indicates that well-known system CA certificates should be used.\n\n                      Implementations MAY define their own sets of CA certificates. Such definitions\n                      MUST use an implementation-specific, prefixed name, such as\n                      `mycompany.com/my-custom-ca-certifcates`.\n\n                      Support: Implementation-specific\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$\n                    type: string\n                required:\n                - hostname\n                type: object\n                x-kubernetes-validations:\n                - message: must not contain both CACertificateRefs and WellKnownCACertificates\n                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")'\n                - message: must specify either CACertificateRefs or WellKnownCACertificates\n                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")\n            required:\n            - targetRefs\n            - validation\n            type: object\n          status:\n            description: Status defines the current state of BackendTLSPolicy.\n            properties:\n              ancestors:\n                description: |-\n                  Ancestors is a list of ancestor resources (usually Gateways) that are\n                  associated with the policy, and the status of the policy with respect to\n                  each ancestor. When this policy attaches to a parent, the controller that\n                  manages the parent and the ancestors MUST add an entry to this list when\n                  the controller first sees the policy and SHOULD update the entry as\n                  appropriate when the relevant ancestor is modified.\n\n                  Note that choosing the relevant ancestor is left to the Policy designers;\n                  an important part of Policy design is designing the right object level at\n                  which to namespace this status.\n\n                  Note also that implementations MUST ONLY populate ancestor status for\n                  the Ancestor resources they are responsible for. Implementations MUST\n                  use the ControllerName field to uniquely identify the entries in this list\n                  that they are responsible for.\n\n                  Note that to achieve this, the list of PolicyAncestorStatus structs\n                  MUST be treated as a map with a composite key, made up of the AncestorRef\n                  and ControllerName fields combined.\n\n                  A maximum of 16 ancestors will be represented in this list. An empty list\n                  means the Policy is not relevant for any ancestors.\n\n                  If this slice is full, implementations MUST NOT add further entries.\n                  Instead they MUST consider the policy unimplementable and signal that\n                  on any related resources such as the ancestor that would be referenced\n                  here. For example, if this list was full on BackendTLSPolicy, no\n                  additional Gateways would be able to reference the Service targeted by\n                  the BackendTLSPolicy.\n                items:\n                  description: |-\n                    PolicyAncestorStatus describes the status of a route with respect to an\n                    associated Ancestor.\n\n                    Ancestors refer to objects that are either the Target of a policy or above it\n                    in terms of object hierarchy. For example, if a policy targets a Service, the\n                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\n                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\n                    useful object to place Policy status on, so we recommend that implementations\n                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers\n                    have a _very_ good reason otherwise.\n\n                    In the context of policy attachment, the Ancestor is used to distinguish which\n                    resource results in a distinct application of this policy. For example, if a policy\n                    targets a Service, it may have a distinct result per attached Gateway.\n\n                    Policies targeting the same resource may have different effects depending on the\n                    ancestors of those resources. For example, different Gateways targeting the same\n                    Service may have different capabilities, especially if they have different underlying\n                    implementations.\n\n                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is\n                    used as a backend in a HTTPRoute that is itself attached to a Gateway.\n                    In this case, the relevant object for status is the Gateway, and that is the\n                    ancestor object referred to in this status.\n\n                    Note that a parent is also an ancestor, so for objects where the parent is the\n                    relevant object for status, this struct SHOULD still be used.\n\n                    This struct is intended to be used in a slice that's effectively a map,\n                    with a composite key made up of the AncestorRef and the ControllerName.\n                  properties:\n                    ancestorRef:\n                      description: |-\n                        AncestorRef corresponds with a ParentRef in the spec that this\n                        PolicyAncestorStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    conditions:\n                      description: Conditions describes the status of the Policy with\n                        respect to the given Ancestor.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                  required:\n                  - ancestorRef\n                  - conditions\n                  - controllerName\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - ancestors\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_gatewayclasses.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: gatewayclasses.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: GatewayClass\n    listKind: GatewayClassList\n    plural: gatewayclasses\n    shortNames:\n    - gc\n    singular: gatewayclass\n  scope: Cluster\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.controllerName\n      name: Controller\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - jsonPath: .spec.description\n      name: Description\n      priority: 1\n      type: string\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          GatewayClass describes a class of Gateways available to the user for creating\n          Gateway resources.\n\n          It is recommended that this resource be used as a template for Gateways. This\n          means that a Gateway is based on the state of the GatewayClass at the time it\n          was created and changes to the GatewayClass or associated parameters are not\n          propagated down to existing Gateways. This recommendation is intended to\n          limit the blast radius of changes to GatewayClass or associated parameters.\n          If implementations choose to propagate GatewayClass changes to existing\n          Gateways, that MUST be clearly documented by the implementation.\n\n          Whenever one or more Gateways are using a GatewayClass, implementations SHOULD\n          add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the\n          associated GatewayClass. This ensures that a GatewayClass associated with a\n          Gateway is not deleted while in use.\n\n          GatewayClass is a Cluster level resource.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of GatewayClass.\n            properties:\n              controllerName:\n                description: |-\n                  ControllerName is the name of the controller that is managing Gateways of\n                  this class. The value of this field MUST be a domain prefixed path.\n\n                  Example: \"example.net/gateway-controller\".\n\n                  This field is not mutable and cannot be empty.\n\n                  Support: Core\n                maxLength: 253\n                minLength: 1\n                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                type: string\n                x-kubernetes-validations:\n                - message: Value is immutable\n                  rule: self == oldSelf\n              description:\n                description: Description helps describe a GatewayClass with more details.\n                maxLength: 64\n                type: string\n              parametersRef:\n                description: |-\n                  ParametersRef is a reference to a resource that contains the configuration\n                  parameters corresponding to the GatewayClass. This is optional if the\n                  controller does not require any additional configuration.\n\n                  ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,\n                  or an implementation-specific custom resource. The resource can be\n                  cluster-scoped or namespace-scoped.\n\n                  If the referent cannot be found, refers to an unsupported kind, or when\n                  the data within that resource is malformed, the GatewayClass SHOULD be\n                  rejected with the \"Accepted\" status condition set to \"False\" and an\n                  \"InvalidParameters\" reason.\n\n                  A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,\n                  the merging behavior is implementation specific.\n                  It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                  Support: Implementation-specific\n                properties:\n                  group:\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    description: Kind is kind of the referent.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.\n                      This field is required when referring to a Namespace-scoped resource and\n                      MUST be unset when referring to a Cluster-scoped resource.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - group\n                - kind\n                - name\n                type: object\n            required:\n            - controllerName\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n            description: |-\n              Status defines the current state of GatewayClass.\n\n              Implementations MUST populate status on all GatewayClass resources which\n              specify their controller name.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                description: |-\n                  Conditions is the current status from the controller for\n                  this GatewayClass.\n\n                  Controllers should prefer to publish conditions using values\n                  of GatewayClassConditionType for the type of each Condition.\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              supportedFeatures:\n                description: |-\n                  SupportedFeatures is the set of features the GatewayClass support.\n                  It MUST be sorted in ascending alphabetical order by the Name key.\n                items:\n                  properties:\n                    name:\n                      description: |-\n                        FeatureName is used to describe distinct features that are covered by\n                        conformance tests.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .spec.controllerName\n      name: Controller\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - jsonPath: .spec.description\n      name: Description\n      priority: 1\n      type: string\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          GatewayClass describes a class of Gateways available to the user for creating\n          Gateway resources.\n\n          It is recommended that this resource be used as a template for Gateways. This\n          means that a Gateway is based on the state of the GatewayClass at the time it\n          was created and changes to the GatewayClass or associated parameters are not\n          propagated down to existing Gateways. This recommendation is intended to\n          limit the blast radius of changes to GatewayClass or associated parameters.\n          If implementations choose to propagate GatewayClass changes to existing\n          Gateways, that MUST be clearly documented by the implementation.\n\n          Whenever one or more Gateways are using a GatewayClass, implementations SHOULD\n          add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the\n          associated GatewayClass. This ensures that a GatewayClass associated with a\n          Gateway is not deleted while in use.\n\n          GatewayClass is a Cluster level resource.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of GatewayClass.\n            properties:\n              controllerName:\n                description: |-\n                  ControllerName is the name of the controller that is managing Gateways of\n                  this class. The value of this field MUST be a domain prefixed path.\n\n                  Example: \"example.net/gateway-controller\".\n\n                  This field is not mutable and cannot be empty.\n\n                  Support: Core\n                maxLength: 253\n                minLength: 1\n                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                type: string\n                x-kubernetes-validations:\n                - message: Value is immutable\n                  rule: self == oldSelf\n              description:\n                description: Description helps describe a GatewayClass with more details.\n                maxLength: 64\n                type: string\n              parametersRef:\n                description: |-\n                  ParametersRef is a reference to a resource that contains the configuration\n                  parameters corresponding to the GatewayClass. This is optional if the\n                  controller does not require any additional configuration.\n\n                  ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,\n                  or an implementation-specific custom resource. The resource can be\n                  cluster-scoped or namespace-scoped.\n\n                  If the referent cannot be found, refers to an unsupported kind, or when\n                  the data within that resource is malformed, the GatewayClass SHOULD be\n                  rejected with the \"Accepted\" status condition set to \"False\" and an\n                  \"InvalidParameters\" reason.\n\n                  A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,\n                  the merging behavior is implementation specific.\n                  It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                  Support: Implementation-specific\n                properties:\n                  group:\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    description: Kind is kind of the referent.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.\n                      This field is required when referring to a Namespace-scoped resource and\n                      MUST be unset when referring to a Cluster-scoped resource.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - group\n                - kind\n                - name\n                type: object\n            required:\n            - controllerName\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n            description: |-\n              Status defines the current state of GatewayClass.\n\n              Implementations MUST populate status on all GatewayClass resources which\n              specify their controller name.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                description: |-\n                  Conditions is the current status from the controller for\n                  this GatewayClass.\n\n                  Controllers should prefer to publish conditions using values\n                  of GatewayClassConditionType for the type of each Condition.\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              supportedFeatures:\n                description: |-\n                  SupportedFeatures is the set of features the GatewayClass support.\n                  It MUST be sorted in ascending alphabetical order by the Name key.\n                items:\n                  properties:\n                    name:\n                      description: |-\n                        FeatureName is used to describe distinct features that are covered by\n                        conformance tests.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_gateways.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: gateways.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: Gateway\n    listKind: GatewayList\n    plural: gateways\n    shortNames:\n    - gtw\n    singular: gateway\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.gatewayClassName\n      name: Class\n      type: string\n    - jsonPath: .status.addresses[*].value\n      name: Address\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          Gateway represents an instance of a service-traffic handling infrastructure\n          by binding Listeners to a set of IP addresses.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses requested for this Gateway. This is optional and behavior can\n                  depend on the implementation. If a value is set in the spec and the\n                  requested address is invalid or unavailable, the implementation MUST\n                  indicate this in an associated entry in GatewayStatus.Conditions.\n\n                  The Addresses field represents a request for the address(es) on the\n                  \"outside of the Gateway\", that traffic bound for this Gateway will use.\n                  This could be the IP address or hostname of an external load balancer or\n                  other networking infrastructure, or some other address that traffic will\n                  be sent to.\n\n                  If no Addresses are specified, the implementation MAY schedule the\n                  Gateway in an implementation-specific manner, assigning an appropriate\n                  set of Addresses.\n\n                  The implementation MUST bind all Listeners to every GatewayAddress that\n                  it assigns to the Gateway and add a corresponding entry in\n                  GatewayStatus.Addresses.\n\n                  Support: Extended\n                items:\n                  description: GatewaySpecAddress describes an address that can be\n                    bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        When a value is unspecified, an implementation SHOULD automatically\n                        assign an address matching the requested type if possible.\n\n                        If an implementation does not support an empty value, they MUST set the\n                        \"Programmed\" condition in status to False with a reason of \"AddressNotAssigned\".\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      type: string\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must be empty or contain only valid characters\n                      (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\")):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: IPAddress values must be unique\n                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n                - message: Hostname values must be unique\n                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n              allowedListeners:\n                description: |-\n                  AllowedListeners defines which ListenerSets can be attached to this Gateway.\n                  The default value is to allow no ListenerSets.\n                properties:\n                  namespaces:\n                    default:\n                      from: None\n                    description: |-\n                      Namespaces defines which namespaces ListenerSets can be attached to this Gateway.\n                      The default value is to allow no ListenerSets.\n                    properties:\n                      from:\n                        default: None\n                        description: |-\n                          From indicates where ListenerSets can attach to this Gateway. Possible\n                          values are:\n\n                          * Same: Only ListenerSets in the same namespace may be attached to this Gateway.\n                          * Selector: ListenerSets in namespaces selected by the selector may be attached to this Gateway.\n                          * All: ListenerSets in all namespaces may be attached to this Gateway.\n                          * None: Only listeners defined in the Gateway's spec are allowed\n\n                          The default value None\n                        enum:\n                        - All\n                        - Selector\n                        - Same\n                        - None\n                        type: string\n                      selector:\n                        description: |-\n                          Selector must be specified when From is set to \"Selector\". In that case,\n                          only ListenerSets in Namespaces matching this Selector will be selected by this\n                          Gateway. This field is ignored for other values of \"From\".\n                        properties:\n                          matchExpressions:\n                            description: matchExpressions is a list of label selector\n                              requirements. The requirements are ANDed.\n                            items:\n                              description: |-\n                                A label selector requirement is a selector that contains values, a key, and an operator that\n                                relates the key and values.\n                              properties:\n                                key:\n                                  description: key is the label key that the selector\n                                    applies to.\n                                  type: string\n                                operator:\n                                  description: |-\n                                    operator represents a key's relationship to a set of values.\n                                    Valid operators are In, NotIn, Exists and DoesNotExist.\n                                  type: string\n                                values:\n                                  description: |-\n                                    values is an array of string values. If the operator is In or NotIn,\n                                    the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                    the values array must be empty. This array is replaced during a strategic\n                                    merge patch.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              required:\n                              - key\n                              - operator\n                              type: object\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          matchLabels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                              map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                              operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                            type: object\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                type: object\n              defaultScope:\n                description: |-\n                  DefaultScope, when set, configures the Gateway as a default Gateway,\n                  meaning it will dynamically and implicitly have Routes (e.g. HTTPRoute)\n                  attached to it, according to the scope configured here.\n\n                  If unset (the default) or set to None, the Gateway will not act as a\n                  default Gateway; if set, the Gateway will claim any Route with a\n                  matching scope set in its UseDefaultGateway field, subject to the usual\n                  rules about which routes the Gateway can attach to.\n\n                  Think carefully before using this functionality! While the normal rules\n                  about which Route can apply are still enforced, it is simply easier for\n                  the wrong Route to be accidentally attached to this Gateway in this\n                  configuration. If the Gateway operator is not also the operator in\n                  control of the scope (e.g. namespace) with tight controls and checks on\n                  what kind of workloads and Routes get added in that scope, we strongly\n                  recommend not using this just because it seems convenient, and instead\n                  stick to direct Route attachment.\n                enum:\n                - All\n                - None\n                type: string\n              gatewayClassName:\n                description: |-\n                  GatewayClassName used for this Gateway. This is the name of a\n                  GatewayClass resource.\n                maxLength: 253\n                minLength: 1\n                type: string\n              infrastructure:\n                description: |-\n                  Infrastructure defines infrastructure level attributes about this Gateway instance.\n\n                  Support: Extended\n                properties:\n                  annotations:\n                    additionalProperties:\n                      description: |-\n                        AnnotationValue is the value of an annotation in Gateway API. This is used\n                        for validation of maps such as TLS options. This roughly matches Kubernetes\n                        annotation validation, although the length validation in that case is based\n                        on the entire size of the annotations struct.\n                      maxLength: 4096\n                      minLength: 0\n                      type: string\n                    description: |-\n                      Annotations that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"annotations\" concepts.\n\n                      An implementation may chose to add additional implementation-specific annotations as they see fit.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Annotation keys must be in the form of an optional\n                        DNS subdomain prefix followed by a required name segment of\n                        up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the annotation key's prefix must be a\n                        DNS subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  labels:\n                    additionalProperties:\n                      description: |-\n                        LabelValue is the value of a label in the Gateway API. This is used for validation\n                        of maps such as Gateway infrastructure labels. This matches the Kubernetes\n                        label validation rules:\n                        * must be 63 characters or less (can be empty),\n                        * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]),\n                        * could contain dashes (-), underscores (_), dots (.), and alphanumerics between.\n\n                        Valid values include:\n\n                        * MyValue\n                        * my.name\n                        * 123-my-value\n                      maxLength: 63\n                      minLength: 0\n                      pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$\n                      type: string\n                    description: |-\n                      Labels that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"labels\" concepts.\n\n                      An implementation may chose to add additional implementation-specific labels as they see fit.\n\n                      If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels\n                      change, it SHOULD clearly warn about this behavior in documentation.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Label keys must be in the form of an optional DNS subdomain\n                        prefix followed by a required name segment of up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the label key's prefix must be a DNS\n                        subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  parametersRef:\n                    description: |-\n                      ParametersRef is a reference to a resource that contains the configuration\n                      parameters corresponding to the Gateway. This is optional if the\n                      controller does not require any additional configuration.\n\n                      This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis\n\n                      The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified,\n                      the merging behavior is implementation specific.\n                      It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                      If the referent cannot be found, refers to an unsupported kind, or when\n                      the data within that resource is malformed, the Gateway SHOULD be\n                      rejected with the \"Accepted\" status condition set to \"False\" and an\n                      \"InvalidParameters\" reason.\n\n                      Support: Implementation-specific\n                    properties:\n                      group:\n                        description: Group is the group of the referent.\n                        maxLength: 253\n                        pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                        type: string\n                      kind:\n                        description: Kind is kind of the referent.\n                        maxLength: 63\n                        minLength: 1\n                        pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                        type: string\n                      name:\n                        description: Name is the name of the referent.\n                        maxLength: 253\n                        minLength: 1\n                        type: string\n                    required:\n                    - group\n                    - kind\n                    - name\n                    type: object\n                type: object\n              listeners:\n                description: |-\n                  Listeners associated with this Gateway. Listeners define\n                  logical endpoints that are bound on this Gateway's addresses.\n                  At least one Listener MUST be specified.\n\n                  ## Distinct Listeners\n\n                  Each Listener in a set of Listeners (for example, in a single Gateway)\n                  MUST be _distinct_, in that a traffic flow MUST be able to be assigned to\n                  exactly one listener. (This section uses \"set of Listeners\" rather than\n                  \"Listeners in a single Gateway\" because implementations MAY merge configuration\n                  from multiple Gateways onto a single data plane, and these rules _also_\n                  apply in that case).\n\n                  Practically, this means that each listener in a set MUST have a unique\n                  combination of Port, Protocol, and, if supported by the protocol, Hostname.\n\n                  Some combinations of port, protocol, and TLS settings are considered\n                  Core support and MUST be supported by implementations based on the objects\n                  they support:\n\n                  HTTPRoute\n\n                  1. HTTPRoute, Port: 80, Protocol: HTTP\n                  2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided\n\n                  TLSRoute\n\n                  1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough\n\n                  \"Distinct\" Listeners have the following property:\n\n                  **The implementation can match inbound requests to a single distinct\n                  Listener**.\n\n                  When multiple Listeners share values for fields (for\n                  example, two Listeners with the same Port value), the implementation\n                  can match requests to only one of the Listeners using other\n                  Listener fields.\n\n                  When multiple listeners have the same value for the Protocol field, then\n                  each of the Listeners with matching Protocol values MUST have different\n                  values for other fields.\n\n                  The set of fields that MUST be different for a Listener differs per protocol.\n                  The following rules define the rules for what fields MUST be considered for\n                  Listeners to be distinct with each protocol currently defined in the\n                  Gateway API spec.\n\n                  The set of listeners that all share a protocol value MUST have _different_\n                  values for _at least one_ of these fields to be distinct:\n\n                  * **HTTP, HTTPS, TLS**: Port, Hostname\n                  * **TCP, UDP**: Port\n\n                  One **very** important rule to call out involves what happens when an\n                  implementation:\n\n                  * Supports TCP protocol Listeners, as well as HTTP, HTTPS, or TLS protocol\n                    Listeners, and\n                  * sees HTTP, HTTPS, or TLS protocols with the same `port` as one with TCP\n                    Protocol.\n\n                  In this case all the Listeners that share a port with the\n                  TCP Listener are not distinct and so MUST NOT be accepted.\n\n                  If an implementation does not support TCP Protocol Listeners, then the\n                  previous rule does not apply, and the TCP Listeners SHOULD NOT be\n                  accepted.\n\n                  Note that the `tls` field is not used for determining if a listener is distinct, because\n                  Listeners that _only_ differ on TLS config will still conflict in all cases.\n\n                  ### Listeners that are distinct only by Hostname\n\n                  When the Listeners are distinct based only on Hostname, inbound request\n                  hostnames MUST match from the most specific to least specific Hostname\n                  values to choose the correct Listener and its associated set of Routes.\n\n                  Exact matches MUST be processed before wildcard matches, and wildcard\n                  matches MUST be processed before fallback (empty Hostname value)\n                  matches. For example, `\"foo.example.com\"` takes precedence over\n                  `\"*.example.com\"`, and `\"*.example.com\"` takes precedence over `\"\"`.\n\n                  Additionally, if there are multiple wildcard entries, more specific\n                  wildcard entries must be processed before less specific wildcard entries.\n                  For example, `\"*.foo.example.com\"` takes precedence over `\"*.example.com\"`.\n\n                  The precise definition here is that the higher the number of dots in the\n                  hostname to the right of the wildcard character, the higher the precedence.\n\n                  The wildcard character will match any number of characters _and dots_ to\n                  the left, however, so `\"*.example.com\"` will match both\n                  `\"foo.bar.example.com\"` _and_ `\"bar.example.com\"`.\n\n                  ## Handling indistinct Listeners\n\n                  If a set of Listeners contains Listeners that are not distinct, then those\n                  Listeners are _Conflicted_, and the implementation MUST set the \"Conflicted\"\n                  condition in the Listener Status to \"True\".\n\n                  The words \"indistinct\" and \"conflicted\" are considered equivalent for the\n                  purpose of this documentation.\n\n                  Implementations MAY choose to accept a Gateway with some Conflicted\n                  Listeners only if they only accept the partial Listener set that contains\n                  no Conflicted Listeners.\n\n                  Specifically, an implementation MAY accept a partial Listener set subject to\n                  the following rules:\n\n                  * The implementation MUST NOT pick one conflicting Listener as the winner.\n                    ALL indistinct Listeners must not be accepted for processing.\n                  * At least one distinct Listener MUST be present, or else the Gateway effectively\n                    contains _no_ Listeners, and must be rejected from processing as a whole.\n\n                  The implementation MUST set a \"ListenersNotValid\" condition on the\n                  Gateway Status when the Gateway contains Conflicted Listeners whether or\n                  not they accept the Gateway. That Condition SHOULD clearly\n                  indicate in the Message which Listeners are conflicted, and which are\n                  Accepted. Additionally, the Listener status for those listeners SHOULD\n                  indicate which Listeners are conflicted and not Accepted.\n\n                  ## General Listener behavior\n\n                  Note that, for all distinct Listeners, requests SHOULD match at most one Listener.\n                  For example, if Listeners are defined for \"foo.example.com\" and \"*.example.com\", a\n                  request to \"foo.example.com\" SHOULD only be routed using routes attached\n                  to the \"foo.example.com\" Listener (and not the \"*.example.com\" Listener).\n\n                  This concept is known as \"Listener Isolation\", and it is an Extended feature\n                  of Gateway API. Implementations that do not support Listener Isolation MUST\n                  clearly document this, and MUST NOT claim support for the\n                  `GatewayHTTPListenerIsolation` feature.\n\n                  Implementations that _do_ support Listener Isolation SHOULD claim support\n                  for the Extended `GatewayHTTPListenerIsolation` feature and pass the associated\n                  conformance tests.\n\n                  ## Compatible Listeners\n\n                  A Gateway's Listeners are considered _compatible_ if:\n\n                  1. They are distinct.\n                  2. The implementation can serve them in compliance with the Addresses\n                     requirement that all Listeners are available on all assigned\n                     addresses.\n\n                  Compatible combinations in Extended support are expected to vary across\n                  implementations. A combination that is compatible for one implementation\n                  may not be compatible for another.\n\n                  For example, an implementation that cannot serve both TCP and UDP listeners\n                  on the same address, or cannot mix HTTPS and generic TLS listens on the same port\n                  would not consider those cases compatible, even though they are distinct.\n\n                  Implementations MAY merge separate Gateways onto a single set of\n                  Addresses if all Listeners across all Gateways are compatible.\n\n                  In a future release the MinItems=1 requirement MAY be dropped.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Listener embodies the concept of a logical endpoint where a Gateway accepts\n                    network connections.\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n\n                        Support: Core\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n                          Note that this does not require the SNI and Host header to be the same.\n                          The semantics of this are described in more detail below.\n\n                        To ensure security, Section 11.1 of RFC-6066 emphasizes that server\n                        implementations that rely on SNI hostname matching MUST also verify\n                        hostnames within the application protocol.\n\n                        Section 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\n                        reuse of a connection by responding with the HTTP 421 Misdirected Request\n                        status code. This indicates that the origin server has rejected the\n                        request because it appears to have been misdirected.\n\n                        To detect misdirected requests, Gateways SHOULD match the authority of\n                        the requests with all the SNI hostname(s) configured across all the\n                        Gateway Listeners on the same port and protocol:\n\n                        * If another Listener has an exact match or more specific wildcard entry,\n                          the Gateway SHOULD return a 421.\n                        * If the current Listener (selected by SNI matching during ClientHello)\n                          does not match the Host:\n                            * If another Listener does match the Host, the Gateway SHOULD return a\n                              421.\n                            * If no other Listener matches the Host, the Gateway MUST return a\n                              404.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n\n                        Support: Core\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    protocol:\n                      description: |-\n                        Protocol specifies the network protocol this listener expects to receive.\n\n                        Support: Core\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n\n                        Support: Core\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - port\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: tls mode must be set for protocol TLS\n                  rule: 'self.all(l, (l.protocol == ''TLS'' ? has(l.tls) && has(l.tls.mode)\n                    && l.tls.mode != '''' : true))'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol\n                    == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname\n                    == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'\n              tls:\n                description: |-\n                  TLS specifies frontend and backend tls configuration for entire gateway.\n\n                  Support: Extended\n                properties:\n                  backend:\n                    description: |-\n                      Backend describes TLS configuration for gateway when connecting\n                      to backends.\n\n                      Note that this contains only details for the Gateway as a TLS client,\n                      and does _not_ imply behavior about how to choose which backend should\n                      get a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\n                      Support: Core\n                    properties:\n                      clientCertificateRef:\n                        description: |-\n                          ClientCertificateRef references an object that contains a client certificate\n                          and its associated private key. It can reference standard Kubernetes resources,\n                          i.e., Secret, or implementation-specific custom resources.\n\n                          A ClientCertificateRef is considered invalid if:\n\n                          * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                            does not exist) or is misconfigured (e.g., a Secret does not contain the keys\n                            named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef`\n                            and the Message of the Condition MUST indicate why the reference is invalid.\n\n                          * It refers to a resource in another namespace UNLESS there is a ReferenceGrant\n                            in the target namespace that allows the certificate to be attached.\n                            If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `RefNotPermitted`.\n\n                          Implementations MAY choose to perform further validation of the certificate\n                          content (e.g., checking expiry or enforcing specific formats). In such cases,\n                          an implementation-specific Reason and Message MUST be set.\n\n                          Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`).\n                          Support: Implementation-specific - Other resource kinds or Secrets with a\n                          different type (e.g., `Opaque`).\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Secret\n                            description: Kind is kind of the referent. For example\n                              \"Secret\".\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the referenced object. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                        required:\n                        - name\n                        type: object\n                    type: object\n                  frontend:\n                    description: |-\n                      Frontend describes TLS config when client connects to Gateway.\n                      Support: Core\n                    properties:\n                      default:\n                        description: |-\n                          Default specifies the default client certificate validation configuration\n                          for all Listeners handling HTTPS traffic, unless a per-port configuration\n                          is defined.\n\n                          support: Core\n                        properties:\n                          validation:\n                            description: |-\n                              Validation holds configuration information for validating the frontend (client).\n                              Setting this field will result in mutual authentication when connecting to the gateway.\n                              In browsers this may result in a dialog appearing\n                              that requests a user to specify the client certificate.\n                              The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                              Support: Core\n                            properties:\n                              caCertificateRefs:\n                                description: |-\n                                  CACertificateRefs contains one or more references to Kubernetes\n                                  objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                  is used as a trust anchor to validate the certificates presented by\n                                  the client.\n\n                                  A CACertificateRef is invalid if:\n\n                                  * It refers to a resource that cannot be resolved (e.g., the\n                                    referenced resource does not exist) or is misconfigured (e.g., a\n                                    ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                    Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                    and the Message of the Condition must indicate which reference is invalid and why.\n\n                                  * It refers to an unknown or unsupported kind of resource. In this\n                                    case, the Reason on all matching HTTPS listeners must be set to\n                                    `InvalidCACertificateKind` and the Message of the Condition must explain\n                                    which kind of resource is unknown or unsupported.\n\n                                  * It refers to a resource in another namespace UNLESS there is a\n                                    ReferenceGrant in the target namespace that allows the CA\n                                    certificate to be attached. If a ReferenceGrant does not allow this\n                                    reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                    MUST be set with the Reason `RefNotPermitted`.\n\n                                  Implementations MAY choose to perform further validation of the\n                                  certificate content (e.g., checking expiry or enforcing specific formats).\n                                  In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                  In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                  condition is set to `status: False` on all targeted listeners (i.e.,\n                                  listeners serving HTTPS on a matching port). The condition MUST\n                                  include a Reason and Message that indicate the cause of the error. If\n                                  ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                  the `Accepted` condition on the listener is set to `status: False`, with\n                                  the Reason `NoValidCACertificate`.\n                                  Implementations MAY choose to support attaching multiple CA certificates\n                                  to a listener, but this behavior is implementation-specific.\n\n                                  Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                  CA certificate in a key named `ca.crt`.\n\n                                  Support: Implementation-specific - More than one reference, other kinds\n                                  of resources, or a single reference that includes multiple certificates.\n                                items:\n                                  description: |-\n                                    ObjectReference identifies an API object including its namespace.\n\n                                    The API object must be valid in the cluster; the Group and Kind must\n                                    be registered in the cluster for this reference to be valid.\n\n                                    References to objects with invalid Group and Kind are not valid, and must\n                                    be rejected by the implementation, with appropriate Conditions set\n                                    on the containing object.\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When set to the empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"ConfigMap\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of the referenced object. When unspecified, the local\n                                        namespace is inferred.\n\n                                        Note that when a namespace different than the local namespace is specified,\n                                        a ReferenceGrant object is required in the referent namespace to allow that\n                                        namespace's owner to accept the reference. See the ReferenceGrant\n                                        documentation for details.\n\n                                        Support: Core\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                maxItems: 8\n                                minItems: 1\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              mode:\n                                default: AllowValidOnly\n                                description: |-\n                                  FrontendValidationMode defines the mode for validating the client certificate.\n                                  There are two possible modes:\n\n                                  - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                    the client presents a valid certificate. This certificate must successfully\n                                    pass validation against the CA certificates specified in `CACertificateRefs`.\n                                  - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                    even if the client certificate is not presented or fails verification.\n\n                                    This approach delegates client authorization to the backend and introduce\n                                    a significant security risk. It should be used in testing environments or\n                                    on a temporary basis in non-testing environments.\n\n                                  Defaults to AllowValidOnly.\n\n                                  Support: Core\n                                enum:\n                                - AllowValidOnly\n                                - AllowInsecureFallback\n                                type: string\n                            required:\n                            - caCertificateRefs\n                            type: object\n                        type: object\n                      perPort:\n                        description: |-\n                          PerPort specifies tls configuration assigned per port.\n                          Per port configuration is optional. Once set this configuration overrides\n                          the default configuration for all Listeners handling HTTPS traffic\n                          that match this port.\n                          Each override port requires a unique TLS configuration.\n\n                          support: Core\n                        items:\n                          properties:\n                            port:\n                              description: |-\n                                The Port indicates the Port Number to which the TLS configuration will be\n                                applied. This configuration will be applied to all Listeners handling HTTPS\n                                traffic that match this port.\n\n                                Support: Core\n                              format: int32\n                              maximum: 65535\n                              minimum: 1\n                              type: integer\n                            tls:\n                              description: |-\n                                TLS store the configuration that will be applied to all Listeners handling\n                                HTTPS traffic and matching given port.\n\n                                Support: Core\n                              properties:\n                                validation:\n                                  description: |-\n                                    Validation holds configuration information for validating the frontend (client).\n                                    Setting this field will result in mutual authentication when connecting to the gateway.\n                                    In browsers this may result in a dialog appearing\n                                    that requests a user to specify the client certificate.\n                                    The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                                    Support: Core\n                                  properties:\n                                    caCertificateRefs:\n                                      description: |-\n                                        CACertificateRefs contains one or more references to Kubernetes\n                                        objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                        is used as a trust anchor to validate the certificates presented by\n                                        the client.\n\n                                        A CACertificateRef is invalid if:\n\n                                        * It refers to a resource that cannot be resolved (e.g., the\n                                          referenced resource does not exist) or is misconfigured (e.g., a\n                                          ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                          Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                          and the Message of the Condition must indicate which reference is invalid and why.\n\n                                        * It refers to an unknown or unsupported kind of resource. In this\n                                          case, the Reason on all matching HTTPS listeners must be set to\n                                          `InvalidCACertificateKind` and the Message of the Condition must explain\n                                          which kind of resource is unknown or unsupported.\n\n                                        * It refers to a resource in another namespace UNLESS there is a\n                                          ReferenceGrant in the target namespace that allows the CA\n                                          certificate to be attached. If a ReferenceGrant does not allow this\n                                          reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                          MUST be set with the Reason `RefNotPermitted`.\n\n                                        Implementations MAY choose to perform further validation of the\n                                        certificate content (e.g., checking expiry or enforcing specific formats).\n                                        In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                        In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                        condition is set to `status: False` on all targeted listeners (i.e.,\n                                        listeners serving HTTPS on a matching port). The condition MUST\n                                        include a Reason and Message that indicate the cause of the error. If\n                                        ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                        the `Accepted` condition on the listener is set to `status: False`, with\n                                        the Reason `NoValidCACertificate`.\n                                        Implementations MAY choose to support attaching multiple CA certificates\n                                        to a listener, but this behavior is implementation-specific.\n\n                                        Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                        CA certificate in a key named `ca.crt`.\n\n                                        Support: Implementation-specific - More than one reference, other kinds\n                                        of resources, or a single reference that includes multiple certificates.\n                                      items:\n                                        description: |-\n                                          ObjectReference identifies an API object including its namespace.\n\n                                          The API object must be valid in the cluster; the Group and Kind must\n                                          be registered in the cluster for this reference to be valid.\n\n                                          References to objects with invalid Group and Kind are not valid, and must\n                                          be rejected by the implementation, with appropriate Conditions set\n                                          on the containing object.\n                                        properties:\n                                          group:\n                                            description: |-\n                                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                              When set to the empty string, core API group is inferred.\n                                            maxLength: 253\n                                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                            type: string\n                                          kind:\n                                            description: Kind is kind of the referent.\n                                              For example \"ConfigMap\" or \"Service\".\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                            type: string\n                                          name:\n                                            description: Name is the name of the referent.\n                                            maxLength: 253\n                                            minLength: 1\n                                            type: string\n                                          namespace:\n                                            description: |-\n                                              Namespace is the namespace of the referenced object. When unspecified, the local\n                                              namespace is inferred.\n\n                                              Note that when a namespace different than the local namespace is specified,\n                                              a ReferenceGrant object is required in the referent namespace to allow that\n                                              namespace's owner to accept the reference. See the ReferenceGrant\n                                              documentation for details.\n\n                                              Support: Core\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                            type: string\n                                        required:\n                                        - group\n                                        - kind\n                                        - name\n                                        type: object\n                                      maxItems: 8\n                                      minItems: 1\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    mode:\n                                      default: AllowValidOnly\n                                      description: |-\n                                        FrontendValidationMode defines the mode for validating the client certificate.\n                                        There are two possible modes:\n\n                                        - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                          the client presents a valid certificate. This certificate must successfully\n                                          pass validation against the CA certificates specified in `CACertificateRefs`.\n                                        - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                          even if the client certificate is not presented or fails verification.\n\n                                          This approach delegates client authorization to the backend and introduce\n                                          a significant security risk. It should be used in testing environments or\n                                          on a temporary basis in non-testing environments.\n\n                                        Defaults to AllowValidOnly.\n\n                                        Support: Core\n                                      enum:\n                                      - AllowValidOnly\n                                      - AllowInsecureFallback\n                                      type: string\n                                  required:\n                                  - caCertificateRefs\n                                  type: object\n                              type: object\n                          required:\n                          - port\n                          - tls\n                          type: object\n                        maxItems: 64\n                        type: array\n                        x-kubernetes-list-map-keys:\n                        - port\n                        x-kubernetes-list-type: map\n                        x-kubernetes-validations:\n                        - message: Port for TLS configuration must be unique within\n                            the Gateway\n                          rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))\n                    required:\n                    - default\n                    type: object\n                type: object\n            required:\n            - gatewayClassName\n            - listeners\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses lists the network addresses that have been bound to the\n                  Gateway.\n\n                  This list may differ from the addresses provided in the spec under some\n                  conditions:\n\n                    * no addresses are specified, all addresses are dynamically assigned\n                    * a combination of specified and dynamic addresses are assigned\n                    * a specified address was unusable (e.g. already in use)\n                items:\n                  description: GatewayStatusAddress describes a network address that\n                    is bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        Value of the address. The validity of the values will depend\n                        on the type and support by the controller.\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - value\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must only contain valid characters (matching\n                      ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    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])?)*$\"\"\"):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              attachedListenerSets:\n                description: |-\n                  AttachedListenerSets represents the total number of ListenerSets that have been\n                  successfully attached to this Gateway.\n\n                  A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n                  - The ListenerSet is selected by the Gateway's AllowedListeners field\n                  - The ListenerSet has a valid ParentRef selecting the Gateway\n                  - The ListenerSet's status has the condition \"Accepted: true\"\n\n                  Uses for this field include troubleshooting AttachedListenerSets attachment and\n                  measuring blast radius/impact of changes to a Gateway.\n                format: int32\n                type: integer\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the Gateway.\n\n                  Implementations should prefer to express Gateway conditions\n                  using the `GatewayConditionType` and `GatewayConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe Gateway state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                  * \"Ready\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener or Route status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners, even if the Accepted condition of an individual Listener is set\n                        to \"False\". The AttachedRoutes number represents the number of Routes with\n                        the Accepted condition set to \"True\" that have been attached to this Listener.\n                        Routes with any other value for the Accepted condition MUST NOT be included\n                        in this count.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds supported by an implementation for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .spec.gatewayClassName\n      name: Class\n      type: string\n    - jsonPath: .status.addresses[*].value\n      name: Address\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          Gateway represents an instance of a service-traffic handling infrastructure\n          by binding Listeners to a set of IP addresses.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses requested for this Gateway. This is optional and behavior can\n                  depend on the implementation. If a value is set in the spec and the\n                  requested address is invalid or unavailable, the implementation MUST\n                  indicate this in an associated entry in GatewayStatus.Conditions.\n\n                  The Addresses field represents a request for the address(es) on the\n                  \"outside of the Gateway\", that traffic bound for this Gateway will use.\n                  This could be the IP address or hostname of an external load balancer or\n                  other networking infrastructure, or some other address that traffic will\n                  be sent to.\n\n                  If no Addresses are specified, the implementation MAY schedule the\n                  Gateway in an implementation-specific manner, assigning an appropriate\n                  set of Addresses.\n\n                  The implementation MUST bind all Listeners to every GatewayAddress that\n                  it assigns to the Gateway and add a corresponding entry in\n                  GatewayStatus.Addresses.\n\n                  Support: Extended\n                items:\n                  description: GatewaySpecAddress describes an address that can be\n                    bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        When a value is unspecified, an implementation SHOULD automatically\n                        assign an address matching the requested type if possible.\n\n                        If an implementation does not support an empty value, they MUST set the\n                        \"Programmed\" condition in status to False with a reason of \"AddressNotAssigned\".\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      type: string\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must be empty or contain only valid characters\n                      (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\")):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: IPAddress values must be unique\n                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n                - message: Hostname values must be unique\n                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n              allowedListeners:\n                description: |-\n                  AllowedListeners defines which ListenerSets can be attached to this Gateway.\n                  The default value is to allow no ListenerSets.\n                properties:\n                  namespaces:\n                    default:\n                      from: None\n                    description: |-\n                      Namespaces defines which namespaces ListenerSets can be attached to this Gateway.\n                      The default value is to allow no ListenerSets.\n                    properties:\n                      from:\n                        default: None\n                        description: |-\n                          From indicates where ListenerSets can attach to this Gateway. Possible\n                          values are:\n\n                          * Same: Only ListenerSets in the same namespace may be attached to this Gateway.\n                          * Selector: ListenerSets in namespaces selected by the selector may be attached to this Gateway.\n                          * All: ListenerSets in all namespaces may be attached to this Gateway.\n                          * None: Only listeners defined in the Gateway's spec are allowed\n\n                          The default value None\n                        enum:\n                        - All\n                        - Selector\n                        - Same\n                        - None\n                        type: string\n                      selector:\n                        description: |-\n                          Selector must be specified when From is set to \"Selector\". In that case,\n                          only ListenerSets in Namespaces matching this Selector will be selected by this\n                          Gateway. This field is ignored for other values of \"From\".\n                        properties:\n                          matchExpressions:\n                            description: matchExpressions is a list of label selector\n                              requirements. The requirements are ANDed.\n                            items:\n                              description: |-\n                                A label selector requirement is a selector that contains values, a key, and an operator that\n                                relates the key and values.\n                              properties:\n                                key:\n                                  description: key is the label key that the selector\n                                    applies to.\n                                  type: string\n                                operator:\n                                  description: |-\n                                    operator represents a key's relationship to a set of values.\n                                    Valid operators are In, NotIn, Exists and DoesNotExist.\n                                  type: string\n                                values:\n                                  description: |-\n                                    values is an array of string values. If the operator is In or NotIn,\n                                    the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                    the values array must be empty. This array is replaced during a strategic\n                                    merge patch.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              required:\n                              - key\n                              - operator\n                              type: object\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          matchLabels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                              map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                              operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                            type: object\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                type: object\n              defaultScope:\n                description: |-\n                  DefaultScope, when set, configures the Gateway as a default Gateway,\n                  meaning it will dynamically and implicitly have Routes (e.g. HTTPRoute)\n                  attached to it, according to the scope configured here.\n\n                  If unset (the default) or set to None, the Gateway will not act as a\n                  default Gateway; if set, the Gateway will claim any Route with a\n                  matching scope set in its UseDefaultGateway field, subject to the usual\n                  rules about which routes the Gateway can attach to.\n\n                  Think carefully before using this functionality! While the normal rules\n                  about which Route can apply are still enforced, it is simply easier for\n                  the wrong Route to be accidentally attached to this Gateway in this\n                  configuration. If the Gateway operator is not also the operator in\n                  control of the scope (e.g. namespace) with tight controls and checks on\n                  what kind of workloads and Routes get added in that scope, we strongly\n                  recommend not using this just because it seems convenient, and instead\n                  stick to direct Route attachment.\n                enum:\n                - All\n                - None\n                type: string\n              gatewayClassName:\n                description: |-\n                  GatewayClassName used for this Gateway. This is the name of a\n                  GatewayClass resource.\n                maxLength: 253\n                minLength: 1\n                type: string\n              infrastructure:\n                description: |-\n                  Infrastructure defines infrastructure level attributes about this Gateway instance.\n\n                  Support: Extended\n                properties:\n                  annotations:\n                    additionalProperties:\n                      description: |-\n                        AnnotationValue is the value of an annotation in Gateway API. This is used\n                        for validation of maps such as TLS options. This roughly matches Kubernetes\n                        annotation validation, although the length validation in that case is based\n                        on the entire size of the annotations struct.\n                      maxLength: 4096\n                      minLength: 0\n                      type: string\n                    description: |-\n                      Annotations that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"annotations\" concepts.\n\n                      An implementation may chose to add additional implementation-specific annotations as they see fit.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Annotation keys must be in the form of an optional\n                        DNS subdomain prefix followed by a required name segment of\n                        up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the annotation key's prefix must be a\n                        DNS subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  labels:\n                    additionalProperties:\n                      description: |-\n                        LabelValue is the value of a label in the Gateway API. This is used for validation\n                        of maps such as Gateway infrastructure labels. This matches the Kubernetes\n                        label validation rules:\n                        * must be 63 characters or less (can be empty),\n                        * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]),\n                        * could contain dashes (-), underscores (_), dots (.), and alphanumerics between.\n\n                        Valid values include:\n\n                        * MyValue\n                        * my.name\n                        * 123-my-value\n                      maxLength: 63\n                      minLength: 0\n                      pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$\n                      type: string\n                    description: |-\n                      Labels that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"labels\" concepts.\n\n                      An implementation may chose to add additional implementation-specific labels as they see fit.\n\n                      If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels\n                      change, it SHOULD clearly warn about this behavior in documentation.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Label keys must be in the form of an optional DNS subdomain\n                        prefix followed by a required name segment of up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the label key's prefix must be a DNS\n                        subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  parametersRef:\n                    description: |-\n                      ParametersRef is a reference to a resource that contains the configuration\n                      parameters corresponding to the Gateway. This is optional if the\n                      controller does not require any additional configuration.\n\n                      This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis\n\n                      The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified,\n                      the merging behavior is implementation specific.\n                      It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                      If the referent cannot be found, refers to an unsupported kind, or when\n                      the data within that resource is malformed, the Gateway SHOULD be\n                      rejected with the \"Accepted\" status condition set to \"False\" and an\n                      \"InvalidParameters\" reason.\n\n                      Support: Implementation-specific\n                    properties:\n                      group:\n                        description: Group is the group of the referent.\n                        maxLength: 253\n                        pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                        type: string\n                      kind:\n                        description: Kind is kind of the referent.\n                        maxLength: 63\n                        minLength: 1\n                        pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                        type: string\n                      name:\n                        description: Name is the name of the referent.\n                        maxLength: 253\n                        minLength: 1\n                        type: string\n                    required:\n                    - group\n                    - kind\n                    - name\n                    type: object\n                type: object\n              listeners:\n                description: |-\n                  Listeners associated with this Gateway. Listeners define\n                  logical endpoints that are bound on this Gateway's addresses.\n                  At least one Listener MUST be specified.\n\n                  ## Distinct Listeners\n\n                  Each Listener in a set of Listeners (for example, in a single Gateway)\n                  MUST be _distinct_, in that a traffic flow MUST be able to be assigned to\n                  exactly one listener. (This section uses \"set of Listeners\" rather than\n                  \"Listeners in a single Gateway\" because implementations MAY merge configuration\n                  from multiple Gateways onto a single data plane, and these rules _also_\n                  apply in that case).\n\n                  Practically, this means that each listener in a set MUST have a unique\n                  combination of Port, Protocol, and, if supported by the protocol, Hostname.\n\n                  Some combinations of port, protocol, and TLS settings are considered\n                  Core support and MUST be supported by implementations based on the objects\n                  they support:\n\n                  HTTPRoute\n\n                  1. HTTPRoute, Port: 80, Protocol: HTTP\n                  2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided\n\n                  TLSRoute\n\n                  1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough\n\n                  \"Distinct\" Listeners have the following property:\n\n                  **The implementation can match inbound requests to a single distinct\n                  Listener**.\n\n                  When multiple Listeners share values for fields (for\n                  example, two Listeners with the same Port value), the implementation\n                  can match requests to only one of the Listeners using other\n                  Listener fields.\n\n                  When multiple listeners have the same value for the Protocol field, then\n                  each of the Listeners with matching Protocol values MUST have different\n                  values for other fields.\n\n                  The set of fields that MUST be different for a Listener differs per protocol.\n                  The following rules define the rules for what fields MUST be considered for\n                  Listeners to be distinct with each protocol currently defined in the\n                  Gateway API spec.\n\n                  The set of listeners that all share a protocol value MUST have _different_\n                  values for _at least one_ of these fields to be distinct:\n\n                  * **HTTP, HTTPS, TLS**: Port, Hostname\n                  * **TCP, UDP**: Port\n\n                  One **very** important rule to call out involves what happens when an\n                  implementation:\n\n                  * Supports TCP protocol Listeners, as well as HTTP, HTTPS, or TLS protocol\n                    Listeners, and\n                  * sees HTTP, HTTPS, or TLS protocols with the same `port` as one with TCP\n                    Protocol.\n\n                  In this case all the Listeners that share a port with the\n                  TCP Listener are not distinct and so MUST NOT be accepted.\n\n                  If an implementation does not support TCP Protocol Listeners, then the\n                  previous rule does not apply, and the TCP Listeners SHOULD NOT be\n                  accepted.\n\n                  Note that the `tls` field is not used for determining if a listener is distinct, because\n                  Listeners that _only_ differ on TLS config will still conflict in all cases.\n\n                  ### Listeners that are distinct only by Hostname\n\n                  When the Listeners are distinct based only on Hostname, inbound request\n                  hostnames MUST match from the most specific to least specific Hostname\n                  values to choose the correct Listener and its associated set of Routes.\n\n                  Exact matches MUST be processed before wildcard matches, and wildcard\n                  matches MUST be processed before fallback (empty Hostname value)\n                  matches. For example, `\"foo.example.com\"` takes precedence over\n                  `\"*.example.com\"`, and `\"*.example.com\"` takes precedence over `\"\"`.\n\n                  Additionally, if there are multiple wildcard entries, more specific\n                  wildcard entries must be processed before less specific wildcard entries.\n                  For example, `\"*.foo.example.com\"` takes precedence over `\"*.example.com\"`.\n\n                  The precise definition here is that the higher the number of dots in the\n                  hostname to the right of the wildcard character, the higher the precedence.\n\n                  The wildcard character will match any number of characters _and dots_ to\n                  the left, however, so `\"*.example.com\"` will match both\n                  `\"foo.bar.example.com\"` _and_ `\"bar.example.com\"`.\n\n                  ## Handling indistinct Listeners\n\n                  If a set of Listeners contains Listeners that are not distinct, then those\n                  Listeners are _Conflicted_, and the implementation MUST set the \"Conflicted\"\n                  condition in the Listener Status to \"True\".\n\n                  The words \"indistinct\" and \"conflicted\" are considered equivalent for the\n                  purpose of this documentation.\n\n                  Implementations MAY choose to accept a Gateway with some Conflicted\n                  Listeners only if they only accept the partial Listener set that contains\n                  no Conflicted Listeners.\n\n                  Specifically, an implementation MAY accept a partial Listener set subject to\n                  the following rules:\n\n                  * The implementation MUST NOT pick one conflicting Listener as the winner.\n                    ALL indistinct Listeners must not be accepted for processing.\n                  * At least one distinct Listener MUST be present, or else the Gateway effectively\n                    contains _no_ Listeners, and must be rejected from processing as a whole.\n\n                  The implementation MUST set a \"ListenersNotValid\" condition on the\n                  Gateway Status when the Gateway contains Conflicted Listeners whether or\n                  not they accept the Gateway. That Condition SHOULD clearly\n                  indicate in the Message which Listeners are conflicted, and which are\n                  Accepted. Additionally, the Listener status for those listeners SHOULD\n                  indicate which Listeners are conflicted and not Accepted.\n\n                  ## General Listener behavior\n\n                  Note that, for all distinct Listeners, requests SHOULD match at most one Listener.\n                  For example, if Listeners are defined for \"foo.example.com\" and \"*.example.com\", a\n                  request to \"foo.example.com\" SHOULD only be routed using routes attached\n                  to the \"foo.example.com\" Listener (and not the \"*.example.com\" Listener).\n\n                  This concept is known as \"Listener Isolation\", and it is an Extended feature\n                  of Gateway API. Implementations that do not support Listener Isolation MUST\n                  clearly document this, and MUST NOT claim support for the\n                  `GatewayHTTPListenerIsolation` feature.\n\n                  Implementations that _do_ support Listener Isolation SHOULD claim support\n                  for the Extended `GatewayHTTPListenerIsolation` feature and pass the associated\n                  conformance tests.\n\n                  ## Compatible Listeners\n\n                  A Gateway's Listeners are considered _compatible_ if:\n\n                  1. They are distinct.\n                  2. The implementation can serve them in compliance with the Addresses\n                     requirement that all Listeners are available on all assigned\n                     addresses.\n\n                  Compatible combinations in Extended support are expected to vary across\n                  implementations. A combination that is compatible for one implementation\n                  may not be compatible for another.\n\n                  For example, an implementation that cannot serve both TCP and UDP listeners\n                  on the same address, or cannot mix HTTPS and generic TLS listens on the same port\n                  would not consider those cases compatible, even though they are distinct.\n\n                  Implementations MAY merge separate Gateways onto a single set of\n                  Addresses if all Listeners across all Gateways are compatible.\n\n                  In a future release the MinItems=1 requirement MAY be dropped.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Listener embodies the concept of a logical endpoint where a Gateway accepts\n                    network connections.\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n\n                        Support: Core\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n                          Note that this does not require the SNI and Host header to be the same.\n                          The semantics of this are described in more detail below.\n\n                        To ensure security, Section 11.1 of RFC-6066 emphasizes that server\n                        implementations that rely on SNI hostname matching MUST also verify\n                        hostnames within the application protocol.\n\n                        Section 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\n                        reuse of a connection by responding with the HTTP 421 Misdirected Request\n                        status code. This indicates that the origin server has rejected the\n                        request because it appears to have been misdirected.\n\n                        To detect misdirected requests, Gateways SHOULD match the authority of\n                        the requests with all the SNI hostname(s) configured across all the\n                        Gateway Listeners on the same port and protocol:\n\n                        * If another Listener has an exact match or more specific wildcard entry,\n                          the Gateway SHOULD return a 421.\n                        * If the current Listener (selected by SNI matching during ClientHello)\n                          does not match the Host:\n                            * If another Listener does match the Host, the Gateway SHOULD return a\n                              421.\n                            * If no other Listener matches the Host, the Gateway MUST return a\n                              404.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n\n                        Support: Core\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    protocol:\n                      description: |-\n                        Protocol specifies the network protocol this listener expects to receive.\n\n                        Support: Core\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n\n                        Support: Core\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - port\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: tls mode must be set for protocol TLS\n                  rule: 'self.all(l, (l.protocol == ''TLS'' ? has(l.tls) && has(l.tls.mode)\n                    && l.tls.mode != '''' : true))'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol\n                    == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname\n                    == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'\n              tls:\n                description: |-\n                  TLS specifies frontend and backend tls configuration for entire gateway.\n\n                  Support: Extended\n                properties:\n                  backend:\n                    description: |-\n                      Backend describes TLS configuration for gateway when connecting\n                      to backends.\n\n                      Note that this contains only details for the Gateway as a TLS client,\n                      and does _not_ imply behavior about how to choose which backend should\n                      get a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\n                      Support: Core\n                    properties:\n                      clientCertificateRef:\n                        description: |-\n                          ClientCertificateRef references an object that contains a client certificate\n                          and its associated private key. It can reference standard Kubernetes resources,\n                          i.e., Secret, or implementation-specific custom resources.\n\n                          A ClientCertificateRef is considered invalid if:\n\n                          * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                            does not exist) or is misconfigured (e.g., a Secret does not contain the keys\n                            named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef`\n                            and the Message of the Condition MUST indicate why the reference is invalid.\n\n                          * It refers to a resource in another namespace UNLESS there is a ReferenceGrant\n                            in the target namespace that allows the certificate to be attached.\n                            If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `RefNotPermitted`.\n\n                          Implementations MAY choose to perform further validation of the certificate\n                          content (e.g., checking expiry or enforcing specific formats). In such cases,\n                          an implementation-specific Reason and Message MUST be set.\n\n                          Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`).\n                          Support: Implementation-specific - Other resource kinds or Secrets with a\n                          different type (e.g., `Opaque`).\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Secret\n                            description: Kind is kind of the referent. For example\n                              \"Secret\".\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the referenced object. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                        required:\n                        - name\n                        type: object\n                    type: object\n                  frontend:\n                    description: |-\n                      Frontend describes TLS config when client connects to Gateway.\n                      Support: Core\n                    properties:\n                      default:\n                        description: |-\n                          Default specifies the default client certificate validation configuration\n                          for all Listeners handling HTTPS traffic, unless a per-port configuration\n                          is defined.\n\n                          support: Core\n                        properties:\n                          validation:\n                            description: |-\n                              Validation holds configuration information for validating the frontend (client).\n                              Setting this field will result in mutual authentication when connecting to the gateway.\n                              In browsers this may result in a dialog appearing\n                              that requests a user to specify the client certificate.\n                              The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                              Support: Core\n                            properties:\n                              caCertificateRefs:\n                                description: |-\n                                  CACertificateRefs contains one or more references to Kubernetes\n                                  objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                  is used as a trust anchor to validate the certificates presented by\n                                  the client.\n\n                                  A CACertificateRef is invalid if:\n\n                                  * It refers to a resource that cannot be resolved (e.g., the\n                                    referenced resource does not exist) or is misconfigured (e.g., a\n                                    ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                    Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                    and the Message of the Condition must indicate which reference is invalid and why.\n\n                                  * It refers to an unknown or unsupported kind of resource. In this\n                                    case, the Reason on all matching HTTPS listeners must be set to\n                                    `InvalidCACertificateKind` and the Message of the Condition must explain\n                                    which kind of resource is unknown or unsupported.\n\n                                  * It refers to a resource in another namespace UNLESS there is a\n                                    ReferenceGrant in the target namespace that allows the CA\n                                    certificate to be attached. If a ReferenceGrant does not allow this\n                                    reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                    MUST be set with the Reason `RefNotPermitted`.\n\n                                  Implementations MAY choose to perform further validation of the\n                                  certificate content (e.g., checking expiry or enforcing specific formats).\n                                  In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                  In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                  condition is set to `status: False` on all targeted listeners (i.e.,\n                                  listeners serving HTTPS on a matching port). The condition MUST\n                                  include a Reason and Message that indicate the cause of the error. If\n                                  ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                  the `Accepted` condition on the listener is set to `status: False`, with\n                                  the Reason `NoValidCACertificate`.\n                                  Implementations MAY choose to support attaching multiple CA certificates\n                                  to a listener, but this behavior is implementation-specific.\n\n                                  Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                  CA certificate in a key named `ca.crt`.\n\n                                  Support: Implementation-specific - More than one reference, other kinds\n                                  of resources, or a single reference that includes multiple certificates.\n                                items:\n                                  description: |-\n                                    ObjectReference identifies an API object including its namespace.\n\n                                    The API object must be valid in the cluster; the Group and Kind must\n                                    be registered in the cluster for this reference to be valid.\n\n                                    References to objects with invalid Group and Kind are not valid, and must\n                                    be rejected by the implementation, with appropriate Conditions set\n                                    on the containing object.\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When set to the empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"ConfigMap\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of the referenced object. When unspecified, the local\n                                        namespace is inferred.\n\n                                        Note that when a namespace different than the local namespace is specified,\n                                        a ReferenceGrant object is required in the referent namespace to allow that\n                                        namespace's owner to accept the reference. See the ReferenceGrant\n                                        documentation for details.\n\n                                        Support: Core\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                maxItems: 8\n                                minItems: 1\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              mode:\n                                default: AllowValidOnly\n                                description: |-\n                                  FrontendValidationMode defines the mode for validating the client certificate.\n                                  There are two possible modes:\n\n                                  - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                    the client presents a valid certificate. This certificate must successfully\n                                    pass validation against the CA certificates specified in `CACertificateRefs`.\n                                  - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                    even if the client certificate is not presented or fails verification.\n\n                                    This approach delegates client authorization to the backend and introduce\n                                    a significant security risk. It should be used in testing environments or\n                                    on a temporary basis in non-testing environments.\n\n                                  Defaults to AllowValidOnly.\n\n                                  Support: Core\n                                enum:\n                                - AllowValidOnly\n                                - AllowInsecureFallback\n                                type: string\n                            required:\n                            - caCertificateRefs\n                            type: object\n                        type: object\n                      perPort:\n                        description: |-\n                          PerPort specifies tls configuration assigned per port.\n                          Per port configuration is optional. Once set this configuration overrides\n                          the default configuration for all Listeners handling HTTPS traffic\n                          that match this port.\n                          Each override port requires a unique TLS configuration.\n\n                          support: Core\n                        items:\n                          properties:\n                            port:\n                              description: |-\n                                The Port indicates the Port Number to which the TLS configuration will be\n                                applied. This configuration will be applied to all Listeners handling HTTPS\n                                traffic that match this port.\n\n                                Support: Core\n                              format: int32\n                              maximum: 65535\n                              minimum: 1\n                              type: integer\n                            tls:\n                              description: |-\n                                TLS store the configuration that will be applied to all Listeners handling\n                                HTTPS traffic and matching given port.\n\n                                Support: Core\n                              properties:\n                                validation:\n                                  description: |-\n                                    Validation holds configuration information for validating the frontend (client).\n                                    Setting this field will result in mutual authentication when connecting to the gateway.\n                                    In browsers this may result in a dialog appearing\n                                    that requests a user to specify the client certificate.\n                                    The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                                    Support: Core\n                                  properties:\n                                    caCertificateRefs:\n                                      description: |-\n                                        CACertificateRefs contains one or more references to Kubernetes\n                                        objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                        is used as a trust anchor to validate the certificates presented by\n                                        the client.\n\n                                        A CACertificateRef is invalid if:\n\n                                        * It refers to a resource that cannot be resolved (e.g., the\n                                          referenced resource does not exist) or is misconfigured (e.g., a\n                                          ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                          Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                          and the Message of the Condition must indicate which reference is invalid and why.\n\n                                        * It refers to an unknown or unsupported kind of resource. In this\n                                          case, the Reason on all matching HTTPS listeners must be set to\n                                          `InvalidCACertificateKind` and the Message of the Condition must explain\n                                          which kind of resource is unknown or unsupported.\n\n                                        * It refers to a resource in another namespace UNLESS there is a\n                                          ReferenceGrant in the target namespace that allows the CA\n                                          certificate to be attached. If a ReferenceGrant does not allow this\n                                          reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                          MUST be set with the Reason `RefNotPermitted`.\n\n                                        Implementations MAY choose to perform further validation of the\n                                        certificate content (e.g., checking expiry or enforcing specific formats).\n                                        In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                        In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                        condition is set to `status: False` on all targeted listeners (i.e.,\n                                        listeners serving HTTPS on a matching port). The condition MUST\n                                        include a Reason and Message that indicate the cause of the error. If\n                                        ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                        the `Accepted` condition on the listener is set to `status: False`, with\n                                        the Reason `NoValidCACertificate`.\n                                        Implementations MAY choose to support attaching multiple CA certificates\n                                        to a listener, but this behavior is implementation-specific.\n\n                                        Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                        CA certificate in a key named `ca.crt`.\n\n                                        Support: Implementation-specific - More than one reference, other kinds\n                                        of resources, or a single reference that includes multiple certificates.\n                                      items:\n                                        description: |-\n                                          ObjectReference identifies an API object including its namespace.\n\n                                          The API object must be valid in the cluster; the Group and Kind must\n                                          be registered in the cluster for this reference to be valid.\n\n                                          References to objects with invalid Group and Kind are not valid, and must\n                                          be rejected by the implementation, with appropriate Conditions set\n                                          on the containing object.\n                                        properties:\n                                          group:\n                                            description: |-\n                                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                              When set to the empty string, core API group is inferred.\n                                            maxLength: 253\n                                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                            type: string\n                                          kind:\n                                            description: Kind is kind of the referent.\n                                              For example \"ConfigMap\" or \"Service\".\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                            type: string\n                                          name:\n                                            description: Name is the name of the referent.\n                                            maxLength: 253\n                                            minLength: 1\n                                            type: string\n                                          namespace:\n                                            description: |-\n                                              Namespace is the namespace of the referenced object. When unspecified, the local\n                                              namespace is inferred.\n\n                                              Note that when a namespace different than the local namespace is specified,\n                                              a ReferenceGrant object is required in the referent namespace to allow that\n                                              namespace's owner to accept the reference. See the ReferenceGrant\n                                              documentation for details.\n\n                                              Support: Core\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                            type: string\n                                        required:\n                                        - group\n                                        - kind\n                                        - name\n                                        type: object\n                                      maxItems: 8\n                                      minItems: 1\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    mode:\n                                      default: AllowValidOnly\n                                      description: |-\n                                        FrontendValidationMode defines the mode for validating the client certificate.\n                                        There are two possible modes:\n\n                                        - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                          the client presents a valid certificate. This certificate must successfully\n                                          pass validation against the CA certificates specified in `CACertificateRefs`.\n                                        - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                          even if the client certificate is not presented or fails verification.\n\n                                          This approach delegates client authorization to the backend and introduce\n                                          a significant security risk. It should be used in testing environments or\n                                          on a temporary basis in non-testing environments.\n\n                                        Defaults to AllowValidOnly.\n\n                                        Support: Core\n                                      enum:\n                                      - AllowValidOnly\n                                      - AllowInsecureFallback\n                                      type: string\n                                  required:\n                                  - caCertificateRefs\n                                  type: object\n                              type: object\n                          required:\n                          - port\n                          - tls\n                          type: object\n                        maxItems: 64\n                        type: array\n                        x-kubernetes-list-map-keys:\n                        - port\n                        x-kubernetes-list-type: map\n                        x-kubernetes-validations:\n                        - message: Port for TLS configuration must be unique within\n                            the Gateway\n                          rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))\n                    required:\n                    - default\n                    type: object\n                type: object\n            required:\n            - gatewayClassName\n            - listeners\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses lists the network addresses that have been bound to the\n                  Gateway.\n\n                  This list may differ from the addresses provided in the spec under some\n                  conditions:\n\n                    * no addresses are specified, all addresses are dynamically assigned\n                    * a combination of specified and dynamic addresses are assigned\n                    * a specified address was unusable (e.g. already in use)\n                items:\n                  description: GatewayStatusAddress describes a network address that\n                    is bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        Value of the address. The validity of the values will depend\n                        on the type and support by the controller.\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - value\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must only contain valid characters (matching\n                      ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    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])?)*$\"\"\"):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              attachedListenerSets:\n                description: |-\n                  AttachedListenerSets represents the total number of ListenerSets that have been\n                  successfully attached to this Gateway.\n\n                  A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n                  - The ListenerSet is selected by the Gateway's AllowedListeners field\n                  - The ListenerSet has a valid ParentRef selecting the Gateway\n                  - The ListenerSet's status has the condition \"Accepted: true\"\n\n                  Uses for this field include troubleshooting AttachedListenerSets attachment and\n                  measuring blast radius/impact of changes to a Gateway.\n                format: int32\n                type: integer\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the Gateway.\n\n                  Implementations should prefer to express Gateway conditions\n                  using the `GatewayConditionType` and `GatewayConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe Gateway state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                  * \"Ready\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener or Route status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners, even if the Accepted condition of an individual Listener is set\n                        to \"False\". The AttachedRoutes number represents the number of Routes with\n                        the Accepted condition set to \"True\" that have been attached to this Listener.\n                        Routes with any other value for the Accepted condition MUST NOT be included\n                        in this count.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds supported by an implementation for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_grpcroutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: grpcroutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: GRPCRoute\n    listKind: GRPCRouteList\n    plural: grpcroutes\n    singular: grpcroute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.hostnames\n      name: Hostnames\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          GRPCRoute provides a way to route gRPC requests. This includes the capability\n          to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header.\n          Filters can be used to specify additional processing steps. Backends specify\n          where matching requests will be routed.\n\n          GRPCRoute falls under extended support within the Gateway API. Within the\n          following specification, the word \"MUST\" indicates that an implementation\n          supporting GRPCRoute must conform to the indicated requirement, but an\n          implementation not supporting this route type need not follow the requirement\n          unless explicitly indicated.\n\n          Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST\n          accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via\n          ALPN. If the implementation does not support this, then it MUST set the\n          \"Accepted\" condition to \"False\" for the affected listener with a reason of\n          \"UnsupportedProtocol\".  Implementations MAY also accept HTTP/2 connections\n          with an upgrade from HTTP/1.\n\n          Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST\n          support HTTP/2 over cleartext TCP (h2c,\n          https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial\n          upgrade from HTTP/1.1, i.e. with prior knowledge\n          (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation\n          does not support this, then it MUST set the \"Accepted\" condition to \"False\"\n          for the affected listener with a reason of \"UnsupportedProtocol\".\n          Implementations MAY also accept HTTP/2 connections with an upgrade from\n          HTTP/1, i.e. without prior knowledge.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of GRPCRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of hostnames to match against the GRPC\n                  Host header to select a GRPCRoute to process the request. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label MUST appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and GRPCRoute, there\n                  MUST be at least one intersecting hostname for the GRPCRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches GRPCRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches GRPCRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `test.example.com` and `*.example.com` would both match. On the other\n                    hand, `example.com` and `test.example.net` would not match.\n\n                  Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                  as a suffix match. That means that a match for `*.example.com` would match\n                  both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                  If both the Listener and GRPCRoute have specified hostnames, any\n                  GRPCRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  GRPCRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` MUST NOT be considered for a match.\n\n                  If both the Listener and GRPCRoute have specified hostnames, and none\n                  match with the criteria above, then the GRPCRoute MUST NOT be accepted by\n                  the implementation. The implementation MUST raise an 'Accepted' Condition\n                  with a status of `False` in the corresponding RouteParentStatus.\n\n                  If a Route (A) of type HTTPRoute or GRPCRoute is attached to a\n                  Listener and that listener already has another Route (B) of the other\n                  type attached and the intersection of the hostnames of A and B is\n                  non-empty, then the implementation MUST accept exactly one of these two\n                  routes, determined by the following criteria, in order:\n\n                  * The oldest Route based on creation timestamp.\n                  * The Route appearing first in alphabetical order by\n                    \"{namespace}/{name}\".\n\n                  The rejected Route MUST raise an 'Accepted' condition with a status of\n                  'False' in the corresponding RouteParentStatus.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                description: Rules are a list of GRPC matchers, filters and actions.\n                items:\n                  description: |-\n                    GRPCRouteRule defines the semantics for matching a gRPC request based on\n                    conditions (matches), processing it (filters), and forwarding the request to\n                    an API object (backendRefs).\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent.\n\n                        Failure behavior here depends on how many BackendRefs are specified and\n                        how many are invalid.\n\n                        If *all* entries in BackendRefs are invalid, and there are also no filters\n                        specified in this route rule, *all* traffic which matches this rule MUST\n                        receive an `UNAVAILABLE` status.\n\n                        See the GRPCBackendRef definition for the rules about what makes a single\n                        GRPCBackendRef invalid.\n\n                        When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for\n                        requests that would have otherwise been routed to an invalid backend. If\n                        multiple backends are specified, and some are invalid, the proportion of\n                        requests that would otherwise have been routed to an invalid backend\n                        MUST receive an `UNAVAILABLE` status.\n\n                        For example, if two backends are specified with equal weights, and one is\n                        invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.\n                        Implementations may choose how that 50 percent is determined.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Core\n                      items:\n                        description: |-\n                          GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n                        properties:\n                          filters:\n                            description: |-\n                              Filters defined at this level MUST be executed if and only if the\n                              request is being forwarded to the backend defined here.\n\n                              Support: Implementation-specific (For broader support of filters, use the\n                              Filters field in GRPCRouteRule.)\n                            items:\n                              description: |-\n                                GRPCRouteFilter defines processing steps that must be completed during the\n                                request or response lifecycle. GRPCRouteFilters are meant as an extension\n                                point to express processing that may be done in Gateway implementations. Some\n                                examples include request or response modification, implementing\n                                authentication strategies, rate-limiting, and traffic shaping. API\n                                guarantee/conformance is defined based on the type of the filter.\n                              properties:\n                                extensionRef:\n                                  description: |-\n                                    ExtensionRef is an optional, implementation-specific extension to the\n                                    \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                                    \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                                    extended filters.\n\n                                    Support: Implementation-specific\n\n                                    This filter can be used multiple times within the same rule.\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When unspecified or empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"HTTPRoute\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                requestHeaderModifier:\n                                  description: |-\n                                    RequestHeaderModifier defines a schema for a filter that modifies request\n                                    headers.\n\n                                    Support: Core\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                requestMirror:\n                                  description: |-\n                                    RequestMirror defines a schema for a filter that mirrors requests.\n                                    Requests are sent to the specified destination, but responses from\n                                    that destination are ignored.\n\n                                    This filter can be used multiple times within the same rule. Note that\n                                    not all implementations will be able to support mirroring to multiple\n                                    backends.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef references a resource where mirrored requests are sent.\n\n                                        Mirrored requests must be sent only to a single destination endpoint\n                                        within this BackendRef, irrespective of how many endpoints are present\n                                        within this BackendRef.\n\n                                        If the referent cannot be found, this BackendRef is invalid and must be\n                                        dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                        condition on the Route status is set to `status: False` and not configure\n                                        this backend in the underlying implementation.\n\n                                        If there is a cross-namespace reference to an *existing* object\n                                        that is not allowed by a ReferenceGrant, the controller must ensure the\n                                        \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                        with the \"RefNotPermitted\" reason and not configure this backend in the\n                                        underlying implementation.\n\n                                        In either error case, the Message of the `ResolvedRefs` Condition\n                                        should be used to provide more detail about the problem.\n\n                                        Support: Extended for Kubernetes Service\n\n                                        Support: Implementation-specific for any other resource\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    fraction:\n                                      description: |-\n                                        Fraction represents the fraction of requests that should be\n                                        mirrored to BackendRef.\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      properties:\n                                        denominator:\n                                          default: 100\n                                          format: int32\n                                          minimum: 1\n                                          type: integer\n                                        numerator:\n                                          format: int32\n                                          minimum: 0\n                                          type: integer\n                                      required:\n                                      - numerator\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: numerator must be less than or equal\n                                          to denominator\n                                        rule: self.numerator <= self.denominator\n                                    percent:\n                                      description: |-\n                                        Percent represents the percentage of requests that should be\n                                        mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                        requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      format: int32\n                                      maximum: 100\n                                      minimum: 0\n                                      type: integer\n                                  required:\n                                  - backendRef\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: Only one of percent or fraction may be\n                                      specified in HTTPRequestMirrorFilter\n                                    rule: '!(has(self.percent) && has(self.fraction))'\n                                responseHeaderModifier:\n                                  description: |-\n                                    ResponseHeaderModifier defines a schema for a filter that modifies response\n                                    headers.\n\n                                    Support: Extended\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                type:\n                                  description: |-\n                                    Type identifies the type of filter to apply. As with other API fields,\n                                    types are classified into three conformance levels:\n\n                                    - Core: Filter types and their corresponding configuration defined by\n                                      \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                      implementations supporting GRPCRoute MUST support core filters.\n\n                                    - Extended: Filter types and their corresponding configuration defined by\n                                      \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                      are encouraged to support extended filters.\n\n                                    - Implementation-specific: Filters that are defined and supported by specific vendors.\n                                      In the future, filters showing convergence in behavior across multiple\n                                      implementations will be considered for inclusion in extended or core\n                                      conformance levels. Filter-specific configuration for such filters\n                                      is specified using the ExtensionRef field. `Type` MUST be set to\n                                      \"ExtensionRef\" for custom filters.\n\n                                    Implementers are encouraged to define custom implementation types to\n                                    extend the core API with implementation-specific behavior.\n\n                                    If a reference to a custom filter type cannot be resolved, the filter\n                                    MUST NOT be skipped. Instead, requests that would have been processed by\n                                    that filter MUST receive a HTTP error response.\n                                  enum:\n                                  - ResponseHeaderModifier\n                                  - RequestHeaderModifier\n                                  - RequestMirror\n                                  - ExtensionRef\n                                  type: string\n                              required:\n                              - type\n                              type: object\n                              x-kubernetes-validations:\n                              - message: filter.requestHeaderModifier must be nil\n                                  if the filter.type is not RequestHeaderModifier\n                                rule: '!(has(self.requestHeaderModifier) && self.type\n                                  != ''RequestHeaderModifier'')'\n                              - message: filter.requestHeaderModifier must be specified\n                                  for RequestHeaderModifier filter.type\n                                rule: '!(!has(self.requestHeaderModifier) && self.type\n                                  == ''RequestHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be nil\n                                  if the filter.type is not ResponseHeaderModifier\n                                rule: '!(has(self.responseHeaderModifier) && self.type\n                                  != ''ResponseHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be specified\n                                  for ResponseHeaderModifier filter.type\n                                rule: '!(!has(self.responseHeaderModifier) && self.type\n                                  == ''ResponseHeaderModifier'')'\n                              - message: filter.requestMirror must be nil if the filter.type\n                                  is not RequestMirror\n                                rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                              - message: filter.requestMirror must be specified for\n                                  RequestMirror filter.type\n                                rule: '!(!has(self.requestMirror) && self.type ==\n                                  ''RequestMirror'')'\n                              - message: filter.extensionRef must be nil if the filter.type\n                                  is not ExtensionRef\n                                rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                              - message: filter.extensionRef must be specified for\n                                  ExtensionRef filter.type\n                                rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-type: atomic\n                            x-kubernetes-validations:\n                            - message: RequestHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                                <= 1\n                            - message: ResponseHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                                <= 1\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    filters:\n                      description: |-\n                        Filters define the filters that are applied to requests that match\n                        this rule.\n\n                        The effects of ordering of multiple behaviors are currently unspecified.\n                        This can change in the future based on feedback during the alpha stage.\n\n                        Conformance-levels at this level are defined based on the type of filter:\n\n                        - ALL core filters MUST be supported by all implementations that support\n                          GRPCRoute.\n                        - Implementers are encouraged to support extended filters.\n                        - Implementation-specific custom filters have no API guarantees across\n                          implementations.\n\n                        Specifying the same filter multiple times is not supported unless explicitly\n                        indicated in the filter.\n\n                        If an implementation cannot support a combination of filters, it must clearly\n                        document that limitation. In cases where incompatible or unsupported\n                        filters are specified and cause the `Accepted` condition to be set to status\n                        `False`, implementations may use the `IncompatibleFilters` reason to specify\n                        this configuration error.\n\n                        Support: Core\n                      items:\n                        description: |-\n                          GRPCRouteFilter defines processing steps that must be completed during the\n                          request or response lifecycle. GRPCRouteFilters are meant as an extension\n                          point to express processing that may be done in Gateway implementations. Some\n                          examples include request or response modification, implementing\n                          authentication strategies, rate-limiting, and traffic shaping. API\n                          guarantee/conformance is defined based on the type of the filter.\n                        properties:\n                          extensionRef:\n                            description: |-\n                              ExtensionRef is an optional, implementation-specific extension to the\n                              \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                              \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                              extended filters.\n\n                              Support: Implementation-specific\n\n                              This filter can be used multiple times within the same rule.\n                            properties:\n                              group:\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is kind of the referent. For example\n                                  \"HTTPRoute\" or \"Service\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                            required:\n                            - group\n                            - kind\n                            - name\n                            type: object\n                          requestHeaderModifier:\n                            description: |-\n                              RequestHeaderModifier defines a schema for a filter that modifies request\n                              headers.\n\n                              Support: Core\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          requestMirror:\n                            description: |-\n                              RequestMirror defines a schema for a filter that mirrors requests.\n                              Requests are sent to the specified destination, but responses from\n                              that destination are ignored.\n\n                              This filter can be used multiple times within the same rule. Note that\n                              not all implementations will be able to support mirroring to multiple\n                              backends.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef references a resource where mirrored requests are sent.\n\n                                  Mirrored requests must be sent only to a single destination endpoint\n                                  within this BackendRef, irrespective of how many endpoints are present\n                                  within this BackendRef.\n\n                                  If the referent cannot be found, this BackendRef is invalid and must be\n                                  dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                  condition on the Route status is set to `status: False` and not configure\n                                  this backend in the underlying implementation.\n\n                                  If there is a cross-namespace reference to an *existing* object\n                                  that is not allowed by a ReferenceGrant, the controller must ensure the\n                                  \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                  with the \"RefNotPermitted\" reason and not configure this backend in the\n                                  underlying implementation.\n\n                                  In either error case, the Message of the `ResolvedRefs` Condition\n                                  should be used to provide more detail about the problem.\n\n                                  Support: Extended for Kubernetes Service\n\n                                  Support: Implementation-specific for any other resource\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              fraction:\n                                description: |-\n                                  Fraction represents the fraction of requests that should be\n                                  mirrored to BackendRef.\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                properties:\n                                  denominator:\n                                    default: 100\n                                    format: int32\n                                    minimum: 1\n                                    type: integer\n                                  numerator:\n                                    format: int32\n                                    minimum: 0\n                                    type: integer\n                                required:\n                                - numerator\n                                type: object\n                                x-kubernetes-validations:\n                                - message: numerator must be less than or equal to\n                                    denominator\n                                  rule: self.numerator <= self.denominator\n                              percent:\n                                description: |-\n                                  Percent represents the percentage of requests that should be\n                                  mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                  requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                format: int32\n                                maximum: 100\n                                minimum: 0\n                                type: integer\n                            required:\n                            - backendRef\n                            type: object\n                            x-kubernetes-validations:\n                            - message: Only one of percent or fraction may be specified\n                                in HTTPRequestMirrorFilter\n                              rule: '!(has(self.percent) && has(self.fraction))'\n                          responseHeaderModifier:\n                            description: |-\n                              ResponseHeaderModifier defines a schema for a filter that modifies response\n                              headers.\n\n                              Support: Extended\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          type:\n                            description: |-\n                              Type identifies the type of filter to apply. As with other API fields,\n                              types are classified into three conformance levels:\n\n                              - Core: Filter types and their corresponding configuration defined by\n                                \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                implementations supporting GRPCRoute MUST support core filters.\n\n                              - Extended: Filter types and their corresponding configuration defined by\n                                \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                are encouraged to support extended filters.\n\n                              - Implementation-specific: Filters that are defined and supported by specific vendors.\n                                In the future, filters showing convergence in behavior across multiple\n                                implementations will be considered for inclusion in extended or core\n                                conformance levels. Filter-specific configuration for such filters\n                                is specified using the ExtensionRef field. `Type` MUST be set to\n                                \"ExtensionRef\" for custom filters.\n\n                              Implementers are encouraged to define custom implementation types to\n                              extend the core API with implementation-specific behavior.\n\n                              If a reference to a custom filter type cannot be resolved, the filter\n                              MUST NOT be skipped. Instead, requests that would have been processed by\n                              that filter MUST receive a HTTP error response.\n                            enum:\n                            - ResponseHeaderModifier\n                            - RequestHeaderModifier\n                            - RequestMirror\n                            - ExtensionRef\n                            type: string\n                        required:\n                        - type\n                        type: object\n                        x-kubernetes-validations:\n                        - message: filter.requestHeaderModifier must be nil if the\n                            filter.type is not RequestHeaderModifier\n                          rule: '!(has(self.requestHeaderModifier) && self.type !=\n                            ''RequestHeaderModifier'')'\n                        - message: filter.requestHeaderModifier must be specified\n                            for RequestHeaderModifier filter.type\n                          rule: '!(!has(self.requestHeaderModifier) && self.type ==\n                            ''RequestHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be nil if the\n                            filter.type is not ResponseHeaderModifier\n                          rule: '!(has(self.responseHeaderModifier) && self.type !=\n                            ''ResponseHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be specified\n                            for ResponseHeaderModifier filter.type\n                          rule: '!(!has(self.responseHeaderModifier) && self.type\n                            == ''ResponseHeaderModifier'')'\n                        - message: filter.requestMirror must be nil if the filter.type\n                            is not RequestMirror\n                          rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                        - message: filter.requestMirror must be specified for RequestMirror\n                            filter.type\n                          rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'\n                        - message: filter.extensionRef must be nil if the filter.type\n                            is not ExtensionRef\n                          rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                        - message: filter.extensionRef must be specified for ExtensionRef\n                            filter.type\n                          rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                      x-kubernetes-validations:\n                      - message: RequestHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                          <= 1\n                      - message: ResponseHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                          <= 1\n                    matches:\n                      description: |-\n                        Matches define conditions used for matching the rule against incoming\n                        gRPC requests. Each match is independent, i.e. this rule will be matched\n                        if **any** one of the matches is satisfied.\n\n                        For example, take the following matches configuration:\n\n                        ```\n                        matches:\n                        - method:\n                            service: foo.bar\n                          headers:\n                            values:\n                              version: 2\n                        - method:\n                            service: foo.bar.v2\n                        ```\n\n                        For a request to match against this rule, it MUST satisfy\n                        EITHER of the two conditions:\n\n                        - service of foo.bar AND contains the header `version: 2`\n                        - service of foo.bar.v2\n\n                        See the documentation for GRPCRouteMatch on how to specify multiple\n                        match conditions to be ANDed together.\n\n                        If no matches are specified, the implementation MUST match every gRPC request.\n\n                        Proxy or Load Balancer routing configuration generated from GRPCRoutes\n                        MUST prioritize rules based on the following criteria, continuing on\n                        ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.\n                        Precedence MUST be given to the rule with the largest number of:\n\n                        * Characters in a matching non-wildcard hostname.\n                        * Characters in a matching hostname.\n                        * Characters in a matching service.\n                        * Characters in a matching method.\n                        * Header matches.\n\n                        If ties still exist across multiple Routes, matching precedence MUST be\n                        determined in order of the following criteria, continuing on ties:\n\n                        * The oldest Route based on creation timestamp.\n                        * The Route appearing first in alphabetical order by\n                          \"{namespace}/{name}\".\n\n                        If ties still exist within the Route that has been given precedence,\n                        matching precedence MUST be granted to the first matching rule meeting\n                        the above criteria.\n                      items:\n                        description: |-\n                          GRPCRouteMatch defines the predicate used to match requests to a given\n                          action. Multiple match types are ANDed together, i.e. the match will\n                          evaluate to true only if all conditions are satisfied.\n\n                          For example, the match below will match a gRPC request only if its service\n                          is `foo` AND it contains the `version: v1` header:\n\n                          ```\n                          matches:\n                            - method:\n                              type: Exact\n                              service: \"foo\"\n                            - headers:\n                              name: \"version\"\n                              value \"v1\"\n\n                          ```\n                        properties:\n                          headers:\n                            description: |-\n                              Headers specifies gRPC request header matchers. Multiple match values are\n                              ANDed together, meaning, a request MUST match all the specified headers\n                              to select the route.\n                            items:\n                              description: |-\n                                GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request\n                                headers.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the gRPC Header to be matched.\n\n                                    If multiple entries specify equivalent header names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent header name MUST be ignored. Due to the\n                                    case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                    equivalent.\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: Type specifies how to match against\n                                    the value of the header.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of the gRPC Header\n                                    to be matched.\n                                  maxLength: 4096\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                          method:\n                            description: |-\n                              Method specifies a gRPC request service/method matcher. If this field is\n                              not specified, all services and methods will match.\n                            properties:\n                              method:\n                                description: |-\n                                  Value of the method to match against. If left empty or omitted, will\n                                  match all services.\n\n                                  At least one of Service and Method MUST be a non-empty string.\n                                maxLength: 1024\n                                type: string\n                              service:\n                                description: |-\n                                  Value of the service to match against. If left empty or omitted, will\n                                  match any service.\n\n                                  At least one of Service and Method MUST be a non-empty string.\n                                maxLength: 1024\n                                type: string\n                              type:\n                                default: Exact\n                                description: |-\n                                  Type specifies how to match against the service and/or method.\n                                  Support: Core (Exact with service and method specified)\n\n                                  Support: Implementation-specific (Exact with method specified but no service specified)\n\n                                  Support: Implementation-specific (RegularExpression)\n                                enum:\n                                - Exact\n                                - RegularExpression\n                                type: string\n                            type: object\n                            x-kubernetes-validations:\n                            - message: One or both of 'service' or 'method' must be\n                                specified\n                              rule: 'has(self.type) ? has(self.service) || has(self.method)\n                                : true'\n                            - message: service must only contain valid characters\n                                (matching ^(?i)\\.?[a-z_][a-z_0-9]*(\\.[a-z_][a-z_0-9]*)*$)\n                              rule: '(!has(self.type) || self.type == ''Exact'') &&\n                                has(self.service) ? self.service.matches(r\"\"\"^(?i)\\.?[a-z_][a-z_0-9]*(\\.[a-z_][a-z_0-9]*)*$\"\"\"):\n                                true'\n                            - message: method must only contain valid characters (matching\n                                ^[A-Za-z_][A-Za-z_0-9]*$)\n                              rule: '(!has(self.type) || self.type == ''Exact'') &&\n                                has(self.method) ? self.method.matches(r\"\"\"^[A-Za-z_][A-Za-z_0-9]*$\"\"\"):\n                                true'\n                        type: object\n                      maxItems: 64\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    sessionPersistence:\n                      description: |-\n                        SessionPersistence defines and configures session persistence\n                        for the route rule.\n\n                        Support: Extended\n                      properties:\n                        absoluteTimeout:\n                          description: |-\n                            AbsoluteTimeout defines the absolute timeout of the persistent\n                            session. Once the AbsoluteTimeout duration has elapsed, the\n                            session becomes invalid.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        cookieConfig:\n                          description: |-\n                            CookieConfig provides configuration settings that are specific\n                            to cookie-based session persistence.\n\n                            Support: Core\n                          properties:\n                            lifetimeType:\n                              default: Session\n                              description: |-\n                                LifetimeType specifies whether the cookie has a permanent or\n                                session-based lifetime. A permanent cookie persists until its\n                                specified expiry time, defined by the Expires or Max-Age cookie\n                                attributes, while a session cookie is deleted when the current\n                                session ends.\n\n                                When set to \"Permanent\", AbsoluteTimeout indicates the\n                                cookie's lifetime via the Expires or Max-Age cookie attributes\n                                and is required.\n\n                                When set to \"Session\", AbsoluteTimeout indicates the\n                                absolute lifetime of the cookie tracked by the gateway and\n                                is optional.\n\n                                Defaults to \"Session\".\n\n                                Support: Core for \"Session\" type\n\n                                Support: Extended for \"Permanent\" type\n                              enum:\n                              - Permanent\n                              - Session\n                              type: string\n                          type: object\n                        idleTimeout:\n                          description: |-\n                            IdleTimeout defines the idle timeout of the persistent session.\n                            Once the session has been idle for more than the specified\n                            IdleTimeout duration, the session becomes invalid.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        sessionName:\n                          description: |-\n                            SessionName defines the name of the persistent session token\n                            which may be reflected in the cookie or the header. Users\n                            should avoid reusing session names to prevent unintended\n                            consequences, such as rejection or unpredictable behavior.\n\n                            Support: Implementation-specific\n                          maxLength: 128\n                          type: string\n                        type:\n                          default: Cookie\n                          description: |-\n                            Type defines the type of session persistence such as through\n                            the use of a header or cookie. Defaults to cookie based session\n                            persistence.\n\n                            Support: Core for \"Cookie\" type\n\n                            Support: Extended for \"Header\" type\n                          enum:\n                          - Cookie\n                          - Header\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: AbsoluteTimeout must be specified when cookie lifetimeType\n                          is Permanent\n                        rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)\n                          || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'\n                      - message: cookieConfig can only be set with type Cookie\n                        rule: '!has(self.cookieConfig) || self.type == ''Cookie'''\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: While 16 rules and 64 matches per rule are allowed, the\n                    total number of matches across all rules in a route must be less\n                    than 128\n                  rule: '(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size()\n                    : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size()\n                    : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size()\n                    : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size()\n                    : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size()\n                    : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size()\n                    : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size()\n                    : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size()\n                    : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size()\n                    : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size()\n                    : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size()\n                    : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size()\n                    : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size()\n                    : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size()\n                    : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size()\n                    : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size()\n                    : 0) : 0) <= 128'\n                - message: Rule name must be unique within the route\n                  rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)\n                    && l1.name == l2.name))\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            type: object\n          status:\n            description: Status defines the current state of GRPCRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_httproutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: httproutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: HTTPRoute\n    listKind: HTTPRouteList\n    plural: httproutes\n    singular: httproute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.hostnames\n      name: Hostnames\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          HTTPRoute provides a way to route HTTP requests. This includes the capability\n          to match requests by hostname, path, header, or query param. Filters can be\n          used to specify additional processing steps. Backends specify where matching\n          requests should be routed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of HTTPRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of hostnames that should match against the HTTP Host\n                  header to select a HTTPRoute used to process the request. Implementations\n                  MUST ignore any port value specified in the HTTP Host header while\n                  performing a match and (absent of any applicable header modification\n                  configuration) MUST forward this header unmodified to the backend.\n\n                  Valid values for Hostnames are determined by RFC 1123 definition of a\n                  hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and HTTPRoute, there\n                  must be at least one intersecting hostname for the HTTPRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `*.example.com`, `test.example.com`, and `foo.test.example.com` would\n                    all match. On the other hand, `example.com` and `test.example.net` would\n                    not match.\n\n                  Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                  as a suffix match. That means that a match for `*.example.com` would match\n                  both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                  If both the Listener and HTTPRoute have specified hostnames, any\n                  HTTPRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  HTTPRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` must not be considered for a match.\n\n                  If both the Listener and HTTPRoute have specified hostnames, and none\n                  match with the criteria above, then the HTTPRoute is not accepted. The\n                  implementation must raise an 'Accepted' Condition with a status of\n                  `False` in the corresponding RouteParentStatus.\n\n                  In the event that multiple HTTPRoutes specify intersecting hostnames (e.g.\n                  overlapping wildcard matching and exact matching hostnames), precedence must\n                  be given to rules from the HTTPRoute with the largest number of:\n\n                  * Characters in a matching non-wildcard hostname.\n                  * Characters in a matching hostname.\n\n                  If ties exist across multiple Routes, the matching precedence rules for\n                  HTTPRouteMatches takes over.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                default:\n                - matches:\n                  - path:\n                      type: PathPrefix\n                      value: /\n                description: Rules are a list of HTTP matchers, filters and actions.\n                items:\n                  description: |-\n                    HTTPRouteRule defines semantics for matching an HTTP request based on\n                    conditions (matches), processing it (filters), and forwarding the request to\n                    an API object (backendRefs).\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent.\n\n                        Failure behavior here depends on how many BackendRefs are specified and\n                        how many are invalid.\n\n                        If *all* entries in BackendRefs are invalid, and there are also no filters\n                        specified in this route rule, *all* traffic which matches this rule MUST\n                        receive a 500 status code.\n\n                        See the HTTPBackendRef definition for the rules about what makes a single\n                        HTTPBackendRef invalid.\n\n                        When a HTTPBackendRef is invalid, 500 status codes MUST be returned for\n                        requests that would have otherwise been routed to an invalid backend. If\n                        multiple backends are specified, and some are invalid, the proportion of\n                        requests that would otherwise have been routed to an invalid backend\n                        MUST receive a 500 status code.\n\n                        For example, if two backends are specified with equal weights, and one is\n                        invalid, 50 percent of traffic must receive a 500. Implementations may\n                        choose how that 50 percent is determined.\n\n                        When a HTTPBackendRef refers to a Service that has no ready endpoints,\n                        implementations SHOULD return a 503 for requests to that backend instead.\n                        If an implementation chooses to do this, all of the above rules for 500 responses\n                        MUST also apply for responses that return a 503.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Core\n                      items:\n                        description: |-\n                          HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n                        properties:\n                          filters:\n                            description: |-\n                              Filters defined at this level should be executed if and only if the\n                              request is being forwarded to the backend defined here.\n\n                              Support: Implementation-specific (For broader support of filters, use the\n                              Filters field in HTTPRouteRule.)\n                            items:\n                              description: |-\n                                HTTPRouteFilter defines processing steps that must be completed during the\n                                request or response lifecycle. HTTPRouteFilters are meant as an extension\n                                point to express processing that may be done in Gateway implementations. Some\n                                examples include request or response modification, implementing\n                                authentication strategies, rate-limiting, and traffic shaping. API\n                                guarantee/conformance is defined based on the type of the filter.\n                              properties:\n                                cors:\n                                  description: |-\n                                    CORS defines a schema for a filter that responds to the\n                                    cross-origin request based on HTTP response header.\n\n                                    Support: Extended\n                                  properties:\n                                    allowCredentials:\n                                      description: |-\n                                        AllowCredentials indicates whether the actual cross-origin request allows\n                                        to include credentials.\n\n                                        When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                        response header with value true (case-sensitive).\n\n                                        When set to false or omitted the gateway will omit the header\n                                        `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                        behavior).\n\n                                        Support: Extended\n                                      type: boolean\n                                    allowHeaders:\n                                      description: |-\n                                        AllowHeaders indicates which HTTP request headers are supported for\n                                        accessing the requested resource.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        When the `AllowHeaders` field is configured with one or more headers, the\n                                        gateway must return the `Access-Control-Allow-Headers` response header\n                                        which value is present in the `AllowHeaders` field.\n\n                                        If any header name in the `Access-Control-Request-Headers` request header\n                                        is not included in the list of header names specified by the response\n                                        header `Access-Control-Allow-Headers`, it will present an error on the\n                                        client side.\n\n                                        If any header name in the `Access-Control-Allow-Headers` response header\n                                        does not recognize by the client, it will also occur an error on the\n                                        client side.\n\n                                        A wildcard indicates that the requests with all HTTP headers are allowed.\n                                        If config contains the wildcard \"*\" in allowHeaders and the request is\n                                        not credentialed, the `Access-Control-Allow-Headers` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Headers from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Headers` response header. When\n                                        also the `AllowCredentials` field is true and `AllowHeaders` field\n                                        is specified with the `*` wildcard, the gateway must specify one or more\n                                        HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                        header. The value of the header `Access-Control-Allow-Headers` is same as\n                                        the `Access-Control-Request-Headers` header provided by the client. If\n                                        the header `Access-Control-Request-Headers` is not included in the\n                                        request, the gateway will omit the `Access-Control-Allow-Headers`\n                                        response header, instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowHeaders cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowMethods:\n                                      description: |-\n                                        AllowMethods indicates which HTTP methods are supported for accessing the\n                                        requested resource.\n\n                                        Valid values are any method defined by RFC9110, along with the special\n                                        value `*`, which represents all HTTP methods are allowed.\n\n                                        Method names are case-sensitive, so these values are also case-sensitive.\n                                        (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                        Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                        response header are separated by a comma (\",\").\n\n                                        A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                        CORS-safelisted methods are always allowed, regardless of whether they\n                                        are specified in the `AllowMethods` field.\n\n                                        When the `AllowMethods` field is configured with one or more methods, the\n                                        gateway must return the `Access-Control-Allow-Methods` response header\n                                        which value is present in the `AllowMethods` field.\n\n                                        If the HTTP method of the `Access-Control-Request-Method` request header\n                                        is not included in the list of methods specified by the response header\n                                        `Access-Control-Allow-Methods`, it will present an error on the client\n                                        side.\n\n                                        If config contains the wildcard \"*\" in allowMethods and the request is\n                                        not credentialed, the `Access-Control-Allow-Methods` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Method from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Methods` response header. When\n                                        also the `AllowCredentials` field is true and `AllowMethods` field\n                                        specified with the `*` wildcard, the gateway must specify one HTTP method\n                                        in the value of the Access-Control-Allow-Methods response header. The\n                                        value of the header `Access-Control-Allow-Methods` is same as the\n                                        `Access-Control-Request-Method` header provided by the client. If the\n                                        header `Access-Control-Request-Method` is not included in the request,\n                                        the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                        instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        enum:\n                                        - GET\n                                        - HEAD\n                                        - POST\n                                        - PUT\n                                        - DELETE\n                                        - CONNECT\n                                        - OPTIONS\n                                        - TRACE\n                                        - PATCH\n                                        - '*'\n                                        type: string\n                                      maxItems: 9\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowMethods cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowOrigins:\n                                      description: |-\n                                        AllowOrigins indicates whether the response can be shared with requested\n                                        resource from the given `Origin`.\n\n                                        The `Origin` consists of a scheme and a host, with an optional port, and\n                                        takes the form `<scheme>://<host>(:<port>)`.\n\n                                        Valid values for scheme are: `http` and `https`.\n\n                                        Valid values for port are any integer between 1 and 65535 (the list of\n                                        available TCP/UDP ports). Note that, if not included, port `80` is\n                                        assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                        origins. This may affect origin matching.\n\n                                        The host part of the origin may contain the wildcard character `*`. These\n                                        wildcard characters behave as follows:\n\n                                        * `*` is a greedy match to the _left_, including any number of\n                                          DNS labels to the left of its position. This also means that\n                                          `*` will include any number of period `.` characters to the\n                                          left of its position.\n                                        * A wildcard by itself matches all hosts.\n\n                                        An origin value that includes _only_ the `*` character indicates requests\n                                        from all `Origin`s are allowed.\n\n                                        When the `AllowOrigins` field is configured with multiple origins, it\n                                        means the server supports clients from multiple origins. If the request\n                                        `Origin` matches the configured allowed origins, the gateway must return\n                                        the given `Origin` and sets value of the header\n                                        `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                        client.\n\n                                        The status code of a successful response to a \"preflight\" request is\n                                        always an OK status (i.e., 204 or 200).\n\n                                        If the request `Origin` does not match the configured allowed origins,\n                                        the gateway returns 204/200 response but doesn't set the relevant\n                                        cross-origin response headers. Alternatively, the gateway responds with\n                                        403 status to the \"preflight\" request is denied, coupled with omitting\n                                        the CORS headers. The cross-origin request fails on the client side.\n                                        Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                        Conversely, if the request `Origin` matches one of the configured\n                                        allowed origins, the gateway sets the response header\n                                        `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                        header provided by the client.\n\n                                        When config has the wildcard (\"*\") in allowOrigins, and the request\n                                        is not credentialed (e.g., it is a preflight request), the\n                                        `Access-Control-Allow-Origin` response header either contains the\n                                        wildcard as well or the Origin from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Origin` response header. When\n                                        also the `AllowCredentials` field is true and `AllowOrigins` field\n                                        specified with the `*` wildcard, the gateway must return a single origin\n                                        in the value of the `Access-Control-Allow-Origin` response header,\n                                        instead of specifying the `*` wildcard. The value of the header\n                                        `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                        the client.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                          encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                          scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                          URIs that include an authority MUST include a fully qualified domain name or\n                                          IP address as the host.\n                                        maxLength: 253\n                                        minLength: 1\n                                        pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowOrigins cannot contain '*' alongside\n                                          other origins\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    exposeHeaders:\n                                      description: |-\n                                        ExposeHeaders indicates which HTTP response headers can be exposed\n                                        to client-side scripts in response to a cross-origin request.\n\n                                        A CORS-safelisted response header is an HTTP header in a CORS response\n                                        that it is considered safe to expose to the client scripts.\n                                        The CORS-safelisted response headers include the following headers:\n                                        `Cache-Control`\n                                        `Content-Language`\n                                        `Content-Length`\n                                        `Content-Type`\n                                        `Expires`\n                                        `Last-Modified`\n                                        `Pragma`\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                        The CORS-safelisted response headers are exposed to client by default.\n\n                                        When an HTTP header name is specified using the `ExposeHeaders` field,\n                                        this additional header will be exposed as part of the response to the\n                                        client.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        A wildcard indicates that the responses with all HTTP headers are exposed\n                                        to clients. The `Access-Control-Expose-Headers` response header can only\n                                        use `*` wildcard as value when the request is not credentialed.\n\n                                        When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                        the request is credentialed, the gateway cannot use the `*` wildcard in\n                                        the `Access-Control-Expose-Headers` response header.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    maxAge:\n                                      default: 5\n                                      description: |-\n                                        MaxAge indicates the duration (in seconds) for the client to cache the\n                                        results of a \"preflight\" request.\n\n                                        The information provided by the `Access-Control-Allow-Methods` and\n                                        `Access-Control-Allow-Headers` response headers can be cached by the\n                                        client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                        The default value of `Access-Control-Max-Age` response header is 5\n                                        (seconds).\n\n                                        When the `MaxAge` field is unspecified, the gateway sets the response\n                                        header \"Access-Control-Max-Age: 5\" by default.\n                                      format: int32\n                                      minimum: 1\n                                      type: integer\n                                  type: object\n                                extensionRef:\n                                  description: |-\n                                    ExtensionRef is an optional, implementation-specific extension to the\n                                    \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                                    \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                                    extended filters.\n\n                                    This filter can be used multiple times within the same rule.\n\n                                    Support: Implementation-specific\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When unspecified or empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"HTTPRoute\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                externalAuth:\n                                  description: |-\n                                    ExternalAuth configures settings related to sending request details\n                                    to an external auth service. The external service MUST authenticate\n                                    the request, and MAY authorize the request as well.\n\n                                    If there is any problem communicating with the external service,\n                                    this filter MUST fail closed.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef is a reference to a backend to send authorization\n                                        requests to.\n\n                                        The backend must speak the selected protocol (GRPC or HTTP) on the\n                                        referenced port.\n\n                                        If the backend service requires TLS, use BackendTLSPolicy to tell the\n                                        implementation to supply the TLS details to be used to connect to that\n                                        backend.\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    forwardBody:\n                                      description: |-\n                                        ForwardBody controls if requests to the authorization server should include\n                                        the body of the client request; and if so, how big that body is allowed\n                                        to be.\n\n                                        It is expected that implementations will buffer the request body up to\n                                        `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n                                        4xx series error (413 or 403 are common examples), and fail processing\n                                        of the filter.\n\n                                        If unset, or `forwardBody.maxSize` is set to `0`, then the body will not\n                                        be forwarded.\n\n                                        Feature Name: HTTPRouteExternalAuthForwardBody\n                                      properties:\n                                        maxSize:\n                                          description: |-\n                                            MaxSize specifies how large in bytes the largest body that will be buffered\n                                            and sent to the authorization server. If the body size is larger than\n                                            `maxSize`, then the body sent to the authorization server must be\n                                            truncated to `maxSize` bytes.\n\n                                            Experimental note: This behavior needs to be checked against\n                                            various dataplanes; it may need to be changed.\n                                            See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\n                                            for more.\n\n                                            If 0, the body will not be sent to the authorization server.\n                                          type: integer\n                                      type: object\n                                    grpc:\n                                      description: |-\n                                        GRPCAuthConfig contains configuration for communication with ext_authz\n                                        protocol-speaking backends.\n\n                                        If unset, implementations must assume the default behavior for each\n                                        included field is intended.\n                                      properties:\n                                        allowedHeaders:\n                                          description: |-\n                                            AllowedRequestHeaders specifies what headers from the client request\n                                            will be sent to the authorization server.\n\n                                            If this list is empty, then all headers must be sent.\n\n                                            If the list has entries, only those entries must be sent.\n                                          items:\n                                            type: string\n                                          maxItems: 64\n                                          type: array\n                                          x-kubernetes-list-type: set\n                                      type: object\n                                    http:\n                                      description: |-\n                                        HTTPAuthConfig contains configuration for communication with HTTP-speaking\n                                        backends.\n\n                                        If unset, implementations must assume the default behavior for each\n                                        included field is intended.\n                                      properties:\n                                        allowedHeaders:\n                                          description: |-\n                                            AllowedRequestHeaders specifies what additional headers from the client request\n                                            will be sent to the authorization server.\n\n                                            The following headers must always be sent to the authorization server,\n                                            regardless of this setting:\n\n                                            * `Host`\n                                            * `Method`\n                                            * `Path`\n                                            * `Content-Length`\n                                            * `Authorization`\n\n                                            If this list is empty, then only those headers must be sent.\n\n                                            Note that `Content-Length` has a special behavior, in that the length\n                                            sent must be correct for the actual request to the external authorization\n                                            server - that is, it must reflect the actual number of bytes sent in the\n                                            body of the request to the authorization server.\n\n                                            So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\n                                            to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\n                                            to anything other than `0`, then the `Content-Length` of the authorization\n                                            request must be set to the actual number of bytes forwarded.\n                                          items:\n                                            type: string\n                                          maxItems: 64\n                                          type: array\n                                          x-kubernetes-list-type: set\n                                        allowedResponseHeaders:\n                                          description: |-\n                                            AllowedResponseHeaders specifies what headers from the authorization response\n                                            will be copied into the request to the backend.\n\n                                            If this list is empty, then all headers from the authorization server\n                                            except Authority or Host must be copied.\n                                          items:\n                                            type: string\n                                          maxItems: 64\n                                          type: array\n                                          x-kubernetes-list-type: set\n                                        path:\n                                          description: |-\n                                            Path sets the prefix that paths from the client request will have added\n                                            when forwarded to the authorization server.\n\n                                            When empty or unspecified, no prefix is added.\n\n                                            Valid values are the same as the \"value\" regex for path values in the `match`\n                                            stanza, and the validation regex will screen out invalid paths in the same way.\n                                            Even with the validation, implementations MUST sanitize this input before using it\n                                            directly.\n                                          maxLength: 1024\n                                          pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$\n                                          type: string\n                                      type: object\n                                    protocol:\n                                      description: |-\n                                        ExternalAuthProtocol describes which protocol to use when communicating with an\n                                        ext_authz authorization server.\n\n                                        When this is set to GRPC, each backend must use the Envoy ext_authz protocol\n                                        on the port specified in `backendRefs`. Requests and responses are defined\n                                        in the protobufs explained at:\n                                        https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\n                                        When this is set to HTTP, each backend must respond with a `200` status\n                                        code in on a successful authorization. Any other code is considered\n                                        an authorization failure.\n\n                                        Feature Names:\n                                        GRPC Support - HTTPRouteExternalAuthGRPC\n                                        HTTP Support - HTTPRouteExternalAuthHTTP\n                                      enum:\n                                      - HTTP\n                                      - GRPC\n                                      type: string\n                                  required:\n                                  - backendRef\n                                  - protocol\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: grpc must be specified when protocol\n                                      is set to 'GRPC'\n                                    rule: 'self.protocol == ''GRPC'' ? has(self.grpc)\n                                      : true'\n                                  - message: protocol must be 'GRPC' when grpc is\n                                      set\n                                    rule: 'has(self.grpc) ? self.protocol == ''GRPC''\n                                      : true'\n                                  - message: http must be specified when protocol\n                                      is set to 'HTTP'\n                                    rule: 'self.protocol == ''HTTP'' ? has(self.http)\n                                      : true'\n                                  - message: protocol must be 'HTTP' when http is\n                                      set\n                                    rule: 'has(self.http) ? self.protocol == ''HTTP''\n                                      : true'\n                                requestHeaderModifier:\n                                  description: |-\n                                    RequestHeaderModifier defines a schema for a filter that modifies request\n                                    headers.\n\n                                    Support: Core\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                requestMirror:\n                                  description: |-\n                                    RequestMirror defines a schema for a filter that mirrors requests.\n                                    Requests are sent to the specified destination, but responses from\n                                    that destination are ignored.\n\n                                    This filter can be used multiple times within the same rule. Note that\n                                    not all implementations will be able to support mirroring to multiple\n                                    backends.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef references a resource where mirrored requests are sent.\n\n                                        Mirrored requests must be sent only to a single destination endpoint\n                                        within this BackendRef, irrespective of how many endpoints are present\n                                        within this BackendRef.\n\n                                        If the referent cannot be found, this BackendRef is invalid and must be\n                                        dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                        condition on the Route status is set to `status: False` and not configure\n                                        this backend in the underlying implementation.\n\n                                        If there is a cross-namespace reference to an *existing* object\n                                        that is not allowed by a ReferenceGrant, the controller must ensure the\n                                        \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                        with the \"RefNotPermitted\" reason and not configure this backend in the\n                                        underlying implementation.\n\n                                        In either error case, the Message of the `ResolvedRefs` Condition\n                                        should be used to provide more detail about the problem.\n\n                                        Support: Extended for Kubernetes Service\n\n                                        Support: Implementation-specific for any other resource\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    fraction:\n                                      description: |-\n                                        Fraction represents the fraction of requests that should be\n                                        mirrored to BackendRef.\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      properties:\n                                        denominator:\n                                          default: 100\n                                          format: int32\n                                          minimum: 1\n                                          type: integer\n                                        numerator:\n                                          format: int32\n                                          minimum: 0\n                                          type: integer\n                                      required:\n                                      - numerator\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: numerator must be less than or equal\n                                          to denominator\n                                        rule: self.numerator <= self.denominator\n                                    percent:\n                                      description: |-\n                                        Percent represents the percentage of requests that should be\n                                        mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                        requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      format: int32\n                                      maximum: 100\n                                      minimum: 0\n                                      type: integer\n                                  required:\n                                  - backendRef\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: Only one of percent or fraction may be\n                                      specified in HTTPRequestMirrorFilter\n                                    rule: '!(has(self.percent) && has(self.fraction))'\n                                requestRedirect:\n                                  description: |-\n                                    RequestRedirect defines a schema for a filter that responds to the\n                                    request with an HTTP redirection.\n\n                                    Support: Core\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the hostname to be used in the value of the `Location`\n                                        header in the response.\n                                        When empty, the hostname in the `Host` header of the request is used.\n\n                                        Support: Core\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines parameters used to modify the path of the incoming request.\n                                        The modified path is then used to construct the `Location` header. When\n                                        empty, the request path is used as-is.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                    port:\n                                      description: |-\n                                        Port is the port to be used in the value of the `Location`\n                                        header in the response.\n\n                                        If no port is specified, the redirect port MUST be derived using the\n                                        following rules:\n\n                                        * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                          port associated with the redirect scheme. Specifically \"http\" to port 80\n                                          and \"https\" to port 443. If the redirect scheme does not have a\n                                          well-known port, the listener port of the Gateway SHOULD be used.\n                                        * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                          Listener port.\n\n                                        Implementations SHOULD NOT add the port number in the 'Location'\n                                        header in the following cases:\n\n                                        * A Location header that will use HTTP (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 80.\n                                        * A Location header that will use HTTPS (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                        Support: Extended\n                                      format: int32\n                                      maximum: 65535\n                                      minimum: 1\n                                      type: integer\n                                    scheme:\n                                      description: |-\n                                        Scheme is the scheme to be used in the value of the `Location` header in\n                                        the response. When empty, the scheme of the request is used.\n\n                                        Scheme redirects can affect the port of the redirect, for more information,\n                                        refer to the documentation for the port field of this filter.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Extended\n                                      enum:\n                                      - http\n                                      - https\n                                      type: string\n                                    statusCode:\n                                      default: 302\n                                      description: |-\n                                        StatusCode is the HTTP status code to be used in response.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Core\n                                      enum:\n                                      - 301\n                                      - 302\n                                      - 303\n                                      - 307\n                                      - 308\n                                      type: integer\n                                  type: object\n                                responseHeaderModifier:\n                                  description: |-\n                                    ResponseHeaderModifier defines a schema for a filter that modifies response\n                                    headers.\n\n                                    Support: Extended\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                type:\n                                  description: |-\n                                    Type identifies the type of filter to apply. As with other API fields,\n                                    types are classified into three conformance levels:\n\n                                    - Core: Filter types and their corresponding configuration defined by\n                                      \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                      implementations must support core filters.\n\n                                    - Extended: Filter types and their corresponding configuration defined by\n                                      \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                      are encouraged to support extended filters.\n\n                                    - Implementation-specific: Filters that are defined and supported by\n                                      specific vendors.\n                                      In the future, filters showing convergence in behavior across multiple\n                                      implementations will be considered for inclusion in extended or core\n                                      conformance levels. Filter-specific configuration for such filters\n                                      is specified using the ExtensionRef field. `Type` should be set to\n                                      \"ExtensionRef\" for custom filters.\n\n                                    Implementers are encouraged to define custom implementation types to\n                                    extend the core API with implementation-specific behavior.\n\n                                    If a reference to a custom filter type cannot be resolved, the filter\n                                    MUST NOT be skipped. Instead, requests that would have been processed by\n                                    that filter MUST receive a HTTP error response.\n\n                                    Note that values may be added to this enum, implementations\n                                    must ensure that unknown values will not cause a crash.\n\n                                    Unknown values here must result in the implementation setting the\n                                    Accepted Condition for the Route to `status: False`, with a\n                                    Reason of `UnsupportedValue`.\n                                  enum:\n                                  - RequestHeaderModifier\n                                  - ResponseHeaderModifier\n                                  - RequestMirror\n                                  - RequestRedirect\n                                  - URLRewrite\n                                  - ExtensionRef\n                                  - CORS\n                                  - ExternalAuth\n                                  type: string\n                                urlRewrite:\n                                  description: |-\n                                    URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                                    Support: Extended\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the value to be used to replace the Host header value during\n                                        forwarding.\n\n                                        Support: Extended\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines a path rewrite.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                  type: object\n                              required:\n                              - type\n                              type: object\n                              x-kubernetes-validations:\n                              - message: filter.cors must be nil if the filter.type\n                                  is not CORS\n                                rule: '!(has(self.cors) && self.type != ''CORS'')'\n                              - message: filter.cors must be specified for CORS filter.type\n                                rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                              - message: filter.requestHeaderModifier must be nil\n                                  if the filter.type is not RequestHeaderModifier\n                                rule: '!(has(self.requestHeaderModifier) && self.type\n                                  != ''RequestHeaderModifier'')'\n                              - message: filter.requestHeaderModifier must be specified\n                                  for RequestHeaderModifier filter.type\n                                rule: '!(!has(self.requestHeaderModifier) && self.type\n                                  == ''RequestHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be nil\n                                  if the filter.type is not ResponseHeaderModifier\n                                rule: '!(has(self.responseHeaderModifier) && self.type\n                                  != ''ResponseHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be specified\n                                  for ResponseHeaderModifier filter.type\n                                rule: '!(!has(self.responseHeaderModifier) && self.type\n                                  == ''ResponseHeaderModifier'')'\n                              - message: filter.requestMirror must be nil if the filter.type\n                                  is not RequestMirror\n                                rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                              - message: filter.requestMirror must be specified for\n                                  RequestMirror filter.type\n                                rule: '!(!has(self.requestMirror) && self.type ==\n                                  ''RequestMirror'')'\n                              - message: filter.requestRedirect must be nil if the\n                                  filter.type is not RequestRedirect\n                                rule: '!(has(self.requestRedirect) && self.type !=\n                                  ''RequestRedirect'')'\n                              - message: filter.requestRedirect must be specified\n                                  for RequestRedirect filter.type\n                                rule: '!(!has(self.requestRedirect) && self.type ==\n                                  ''RequestRedirect'')'\n                              - message: filter.urlRewrite must be nil if the filter.type\n                                  is not URLRewrite\n                                rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                              - message: filter.urlRewrite must be specified for URLRewrite\n                                  filter.type\n                                rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                              - message: filter.extensionRef must be nil if the filter.type\n                                  is not ExtensionRef\n                                rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                              - message: filter.extensionRef must be specified for\n                                  ExtensionRef filter.type\n                                rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                              - message: filter.externalAuth must be nil if the filter.type\n                                  is not ExternalAuth\n                                rule: '!(has(self.externalAuth) && self.type != ''ExternalAuth'')'\n                              - message: filter.externalAuth must be specified for\n                                  ExternalAuth filter.type\n                                rule: '!(!has(self.externalAuth) && self.type == ''ExternalAuth'')'\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-type: atomic\n                            x-kubernetes-validations:\n                            - message: May specify either httpRouteFilterRequestRedirect\n                                or httpRouteFilterRequestRewrite, but not both\n                              rule: '!(self.exists(f, f.type == ''RequestRedirect'')\n                                && self.exists(f, f.type == ''URLRewrite''))'\n                            - message: RequestHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                                <= 1\n                            - message: ResponseHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                                <= 1\n                            - message: RequestRedirect filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestRedirect').size()\n                                <= 1\n                            - message: URLRewrite filter cannot be repeated\n                              rule: self.filter(f, f.type == 'URLRewrite').size()\n                                <= 1\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    filters:\n                      description: |-\n                        Filters define the filters that are applied to requests that match\n                        this rule.\n\n                        Wherever possible, implementations SHOULD implement filters in the order\n                        they are specified.\n\n                        Implementations MAY choose to implement this ordering strictly, rejecting\n                        any combination or order of filters that cannot be supported. If implementations\n                        choose a strict interpretation of filter ordering, they MUST clearly document\n                        that behavior.\n\n                        To reject an invalid combination or order of filters, implementations SHOULD\n                        consider the Route Rules with this configuration invalid. If all Route Rules\n                        in a Route are invalid, the entire Route would be considered invalid. If only\n                        a portion of Route Rules are invalid, implementations MUST set the\n                        \"PartiallyInvalid\" condition for the Route.\n\n                        Conformance-levels at this level are defined based on the type of filter:\n\n                        - ALL core filters MUST be supported by all implementations.\n                        - Implementers are encouraged to support extended filters.\n                        - Implementation-specific custom filters have no API guarantees across\n                          implementations.\n\n                        Specifying the same filter multiple times is not supported unless explicitly\n                        indicated in the filter.\n\n                        All filters are expected to be compatible with each other except for the\n                        URLRewrite and RequestRedirect filters, which may not be combined. If an\n                        implementation cannot support other combinations of filters, they must clearly\n                        document that limitation. In cases where incompatible or unsupported\n                        filters are specified and cause the `Accepted` condition to be set to status\n                        `False`, implementations may use the `IncompatibleFilters` reason to specify\n                        this configuration error.\n\n                        Support: Core\n                      items:\n                        description: |-\n                          HTTPRouteFilter defines processing steps that must be completed during the\n                          request or response lifecycle. HTTPRouteFilters are meant as an extension\n                          point to express processing that may be done in Gateway implementations. Some\n                          examples include request or response modification, implementing\n                          authentication strategies, rate-limiting, and traffic shaping. API\n                          guarantee/conformance is defined based on the type of the filter.\n                        properties:\n                          cors:\n                            description: |-\n                              CORS defines a schema for a filter that responds to the\n                              cross-origin request based on HTTP response header.\n\n                              Support: Extended\n                            properties:\n                              allowCredentials:\n                                description: |-\n                                  AllowCredentials indicates whether the actual cross-origin request allows\n                                  to include credentials.\n\n                                  When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                  response header with value true (case-sensitive).\n\n                                  When set to false or omitted the gateway will omit the header\n                                  `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                  behavior).\n\n                                  Support: Extended\n                                type: boolean\n                              allowHeaders:\n                                description: |-\n                                  AllowHeaders indicates which HTTP request headers are supported for\n                                  accessing the requested resource.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  When the `AllowHeaders` field is configured with one or more headers, the\n                                  gateway must return the `Access-Control-Allow-Headers` response header\n                                  which value is present in the `AllowHeaders` field.\n\n                                  If any header name in the `Access-Control-Request-Headers` request header\n                                  is not included in the list of header names specified by the response\n                                  header `Access-Control-Allow-Headers`, it will present an error on the\n                                  client side.\n\n                                  If any header name in the `Access-Control-Allow-Headers` response header\n                                  does not recognize by the client, it will also occur an error on the\n                                  client side.\n\n                                  A wildcard indicates that the requests with all HTTP headers are allowed.\n                                  If config contains the wildcard \"*\" in allowHeaders and the request is\n                                  not credentialed, the `Access-Control-Allow-Headers` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Headers from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Headers` response header. When\n                                  also the `AllowCredentials` field is true and `AllowHeaders` field\n                                  is specified with the `*` wildcard, the gateway must specify one or more\n                                  HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                  header. The value of the header `Access-Control-Allow-Headers` is same as\n                                  the `Access-Control-Request-Headers` header provided by the client. If\n                                  the header `Access-Control-Request-Headers` is not included in the\n                                  request, the gateway will omit the `Access-Control-Allow-Headers`\n                                  response header, instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowHeaders cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowMethods:\n                                description: |-\n                                  AllowMethods indicates which HTTP methods are supported for accessing the\n                                  requested resource.\n\n                                  Valid values are any method defined by RFC9110, along with the special\n                                  value `*`, which represents all HTTP methods are allowed.\n\n                                  Method names are case-sensitive, so these values are also case-sensitive.\n                                  (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                  Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                  response header are separated by a comma (\",\").\n\n                                  A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                  CORS-safelisted methods are always allowed, regardless of whether they\n                                  are specified in the `AllowMethods` field.\n\n                                  When the `AllowMethods` field is configured with one or more methods, the\n                                  gateway must return the `Access-Control-Allow-Methods` response header\n                                  which value is present in the `AllowMethods` field.\n\n                                  If the HTTP method of the `Access-Control-Request-Method` request header\n                                  is not included in the list of methods specified by the response header\n                                  `Access-Control-Allow-Methods`, it will present an error on the client\n                                  side.\n\n                                  If config contains the wildcard \"*\" in allowMethods and the request is\n                                  not credentialed, the `Access-Control-Allow-Methods` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Method from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Methods` response header. When\n                                  also the `AllowCredentials` field is true and `AllowMethods` field\n                                  specified with the `*` wildcard, the gateway must specify one HTTP method\n                                  in the value of the Access-Control-Allow-Methods response header. The\n                                  value of the header `Access-Control-Allow-Methods` is same as the\n                                  `Access-Control-Request-Method` header provided by the client. If the\n                                  header `Access-Control-Request-Method` is not included in the request,\n                                  the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                  instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  enum:\n                                  - GET\n                                  - HEAD\n                                  - POST\n                                  - PUT\n                                  - DELETE\n                                  - CONNECT\n                                  - OPTIONS\n                                  - TRACE\n                                  - PATCH\n                                  - '*'\n                                  type: string\n                                maxItems: 9\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowMethods cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowOrigins:\n                                description: |-\n                                  AllowOrigins indicates whether the response can be shared with requested\n                                  resource from the given `Origin`.\n\n                                  The `Origin` consists of a scheme and a host, with an optional port, and\n                                  takes the form `<scheme>://<host>(:<port>)`.\n\n                                  Valid values for scheme are: `http` and `https`.\n\n                                  Valid values for port are any integer between 1 and 65535 (the list of\n                                  available TCP/UDP ports). Note that, if not included, port `80` is\n                                  assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                  origins. This may affect origin matching.\n\n                                  The host part of the origin may contain the wildcard character `*`. These\n                                  wildcard characters behave as follows:\n\n                                  * `*` is a greedy match to the _left_, including any number of\n                                    DNS labels to the left of its position. This also means that\n                                    `*` will include any number of period `.` characters to the\n                                    left of its position.\n                                  * A wildcard by itself matches all hosts.\n\n                                  An origin value that includes _only_ the `*` character indicates requests\n                                  from all `Origin`s are allowed.\n\n                                  When the `AllowOrigins` field is configured with multiple origins, it\n                                  means the server supports clients from multiple origins. If the request\n                                  `Origin` matches the configured allowed origins, the gateway must return\n                                  the given `Origin` and sets value of the header\n                                  `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                  client.\n\n                                  The status code of a successful response to a \"preflight\" request is\n                                  always an OK status (i.e., 204 or 200).\n\n                                  If the request `Origin` does not match the configured allowed origins,\n                                  the gateway returns 204/200 response but doesn't set the relevant\n                                  cross-origin response headers. Alternatively, the gateway responds with\n                                  403 status to the \"preflight\" request is denied, coupled with omitting\n                                  the CORS headers. The cross-origin request fails on the client side.\n                                  Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                  Conversely, if the request `Origin` matches one of the configured\n                                  allowed origins, the gateway sets the response header\n                                  `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                  header provided by the client.\n\n                                  When config has the wildcard (\"*\") in allowOrigins, and the request\n                                  is not credentialed (e.g., it is a preflight request), the\n                                  `Access-Control-Allow-Origin` response header either contains the\n                                  wildcard as well or the Origin from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Origin` response header. When\n                                  also the `AllowCredentials` field is true and `AllowOrigins` field\n                                  specified with the `*` wildcard, the gateway must return a single origin\n                                  in the value of the `Access-Control-Allow-Origin` response header,\n                                  instead of specifying the `*` wildcard. The value of the header\n                                  `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                  the client.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                    encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                    scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                    URIs that include an authority MUST include a fully qualified domain name or\n                                    IP address as the host.\n                                  maxLength: 253\n                                  minLength: 1\n                                  pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowOrigins cannot contain '*' alongside\n                                    other origins\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              exposeHeaders:\n                                description: |-\n                                  ExposeHeaders indicates which HTTP response headers can be exposed\n                                  to client-side scripts in response to a cross-origin request.\n\n                                  A CORS-safelisted response header is an HTTP header in a CORS response\n                                  that it is considered safe to expose to the client scripts.\n                                  The CORS-safelisted response headers include the following headers:\n                                  `Cache-Control`\n                                  `Content-Language`\n                                  `Content-Length`\n                                  `Content-Type`\n                                  `Expires`\n                                  `Last-Modified`\n                                  `Pragma`\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                  The CORS-safelisted response headers are exposed to client by default.\n\n                                  When an HTTP header name is specified using the `ExposeHeaders` field,\n                                  this additional header will be exposed as part of the response to the\n                                  client.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  A wildcard indicates that the responses with all HTTP headers are exposed\n                                  to clients. The `Access-Control-Expose-Headers` response header can only\n                                  use `*` wildcard as value when the request is not credentialed.\n\n                                  When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                  the request is credentialed, the gateway cannot use the `*` wildcard in\n                                  the `Access-Control-Expose-Headers` response header.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                              maxAge:\n                                default: 5\n                                description: |-\n                                  MaxAge indicates the duration (in seconds) for the client to cache the\n                                  results of a \"preflight\" request.\n\n                                  The information provided by the `Access-Control-Allow-Methods` and\n                                  `Access-Control-Allow-Headers` response headers can be cached by the\n                                  client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                  The default value of `Access-Control-Max-Age` response header is 5\n                                  (seconds).\n\n                                  When the `MaxAge` field is unspecified, the gateway sets the response\n                                  header \"Access-Control-Max-Age: 5\" by default.\n                                format: int32\n                                minimum: 1\n                                type: integer\n                            type: object\n                          extensionRef:\n                            description: |-\n                              ExtensionRef is an optional, implementation-specific extension to the\n                              \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                              \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                              extended filters.\n\n                              This filter can be used multiple times within the same rule.\n\n                              Support: Implementation-specific\n                            properties:\n                              group:\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is kind of the referent. For example\n                                  \"HTTPRoute\" or \"Service\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                            required:\n                            - group\n                            - kind\n                            - name\n                            type: object\n                          externalAuth:\n                            description: |-\n                              ExternalAuth configures settings related to sending request details\n                              to an external auth service. The external service MUST authenticate\n                              the request, and MAY authorize the request as well.\n\n                              If there is any problem communicating with the external service,\n                              this filter MUST fail closed.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef is a reference to a backend to send authorization\n                                  requests to.\n\n                                  The backend must speak the selected protocol (GRPC or HTTP) on the\n                                  referenced port.\n\n                                  If the backend service requires TLS, use BackendTLSPolicy to tell the\n                                  implementation to supply the TLS details to be used to connect to that\n                                  backend.\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              forwardBody:\n                                description: |-\n                                  ForwardBody controls if requests to the authorization server should include\n                                  the body of the client request; and if so, how big that body is allowed\n                                  to be.\n\n                                  It is expected that implementations will buffer the request body up to\n                                  `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n                                  4xx series error (413 or 403 are common examples), and fail processing\n                                  of the filter.\n\n                                  If unset, or `forwardBody.maxSize` is set to `0`, then the body will not\n                                  be forwarded.\n\n                                  Feature Name: HTTPRouteExternalAuthForwardBody\n                                properties:\n                                  maxSize:\n                                    description: |-\n                                      MaxSize specifies how large in bytes the largest body that will be buffered\n                                      and sent to the authorization server. If the body size is larger than\n                                      `maxSize`, then the body sent to the authorization server must be\n                                      truncated to `maxSize` bytes.\n\n                                      Experimental note: This behavior needs to be checked against\n                                      various dataplanes; it may need to be changed.\n                                      See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\n                                      for more.\n\n                                      If 0, the body will not be sent to the authorization server.\n                                    type: integer\n                                type: object\n                              grpc:\n                                description: |-\n                                  GRPCAuthConfig contains configuration for communication with ext_authz\n                                  protocol-speaking backends.\n\n                                  If unset, implementations must assume the default behavior for each\n                                  included field is intended.\n                                properties:\n                                  allowedHeaders:\n                                    description: |-\n                                      AllowedRequestHeaders specifies what headers from the client request\n                                      will be sent to the authorization server.\n\n                                      If this list is empty, then all headers must be sent.\n\n                                      If the list has entries, only those entries must be sent.\n                                    items:\n                                      type: string\n                                    maxItems: 64\n                                    type: array\n                                    x-kubernetes-list-type: set\n                                type: object\n                              http:\n                                description: |-\n                                  HTTPAuthConfig contains configuration for communication with HTTP-speaking\n                                  backends.\n\n                                  If unset, implementations must assume the default behavior for each\n                                  included field is intended.\n                                properties:\n                                  allowedHeaders:\n                                    description: |-\n                                      AllowedRequestHeaders specifies what additional headers from the client request\n                                      will be sent to the authorization server.\n\n                                      The following headers must always be sent to the authorization server,\n                                      regardless of this setting:\n\n                                      * `Host`\n                                      * `Method`\n                                      * `Path`\n                                      * `Content-Length`\n                                      * `Authorization`\n\n                                      If this list is empty, then only those headers must be sent.\n\n                                      Note that `Content-Length` has a special behavior, in that the length\n                                      sent must be correct for the actual request to the external authorization\n                                      server - that is, it must reflect the actual number of bytes sent in the\n                                      body of the request to the authorization server.\n\n                                      So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\n                                      to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\n                                      to anything other than `0`, then the `Content-Length` of the authorization\n                                      request must be set to the actual number of bytes forwarded.\n                                    items:\n                                      type: string\n                                    maxItems: 64\n                                    type: array\n                                    x-kubernetes-list-type: set\n                                  allowedResponseHeaders:\n                                    description: |-\n                                      AllowedResponseHeaders specifies what headers from the authorization response\n                                      will be copied into the request to the backend.\n\n                                      If this list is empty, then all headers from the authorization server\n                                      except Authority or Host must be copied.\n                                    items:\n                                      type: string\n                                    maxItems: 64\n                                    type: array\n                                    x-kubernetes-list-type: set\n                                  path:\n                                    description: |-\n                                      Path sets the prefix that paths from the client request will have added\n                                      when forwarded to the authorization server.\n\n                                      When empty or unspecified, no prefix is added.\n\n                                      Valid values are the same as the \"value\" regex for path values in the `match`\n                                      stanza, and the validation regex will screen out invalid paths in the same way.\n                                      Even with the validation, implementations MUST sanitize this input before using it\n                                      directly.\n                                    maxLength: 1024\n                                    pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$\n                                    type: string\n                                type: object\n                              protocol:\n                                description: |-\n                                  ExternalAuthProtocol describes which protocol to use when communicating with an\n                                  ext_authz authorization server.\n\n                                  When this is set to GRPC, each backend must use the Envoy ext_authz protocol\n                                  on the port specified in `backendRefs`. Requests and responses are defined\n                                  in the protobufs explained at:\n                                  https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\n                                  When this is set to HTTP, each backend must respond with a `200` status\n                                  code in on a successful authorization. Any other code is considered\n                                  an authorization failure.\n\n                                  Feature Names:\n                                  GRPC Support - HTTPRouteExternalAuthGRPC\n                                  HTTP Support - HTTPRouteExternalAuthHTTP\n                                enum:\n                                - HTTP\n                                - GRPC\n                                type: string\n                            required:\n                            - backendRef\n                            - protocol\n                            type: object\n                            x-kubernetes-validations:\n                            - message: grpc must be specified when protocol is set\n                                to 'GRPC'\n                              rule: 'self.protocol == ''GRPC'' ? has(self.grpc) :\n                                true'\n                            - message: protocol must be 'GRPC' when grpc is set\n                              rule: 'has(self.grpc) ? self.protocol == ''GRPC'' :\n                                true'\n                            - message: http must be specified when protocol is set\n                                to 'HTTP'\n                              rule: 'self.protocol == ''HTTP'' ? has(self.http) :\n                                true'\n                            - message: protocol must be 'HTTP' when http is set\n                              rule: 'has(self.http) ? self.protocol == ''HTTP'' :\n                                true'\n                          requestHeaderModifier:\n                            description: |-\n                              RequestHeaderModifier defines a schema for a filter that modifies request\n                              headers.\n\n                              Support: Core\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          requestMirror:\n                            description: |-\n                              RequestMirror defines a schema for a filter that mirrors requests.\n                              Requests are sent to the specified destination, but responses from\n                              that destination are ignored.\n\n                              This filter can be used multiple times within the same rule. Note that\n                              not all implementations will be able to support mirroring to multiple\n                              backends.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef references a resource where mirrored requests are sent.\n\n                                  Mirrored requests must be sent only to a single destination endpoint\n                                  within this BackendRef, irrespective of how many endpoints are present\n                                  within this BackendRef.\n\n                                  If the referent cannot be found, this BackendRef is invalid and must be\n                                  dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                  condition on the Route status is set to `status: False` and not configure\n                                  this backend in the underlying implementation.\n\n                                  If there is a cross-namespace reference to an *existing* object\n                                  that is not allowed by a ReferenceGrant, the controller must ensure the\n                                  \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                  with the \"RefNotPermitted\" reason and not configure this backend in the\n                                  underlying implementation.\n\n                                  In either error case, the Message of the `ResolvedRefs` Condition\n                                  should be used to provide more detail about the problem.\n\n                                  Support: Extended for Kubernetes Service\n\n                                  Support: Implementation-specific for any other resource\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              fraction:\n                                description: |-\n                                  Fraction represents the fraction of requests that should be\n                                  mirrored to BackendRef.\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                properties:\n                                  denominator:\n                                    default: 100\n                                    format: int32\n                                    minimum: 1\n                                    type: integer\n                                  numerator:\n                                    format: int32\n                                    minimum: 0\n                                    type: integer\n                                required:\n                                - numerator\n                                type: object\n                                x-kubernetes-validations:\n                                - message: numerator must be less than or equal to\n                                    denominator\n                                  rule: self.numerator <= self.denominator\n                              percent:\n                                description: |-\n                                  Percent represents the percentage of requests that should be\n                                  mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                  requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                format: int32\n                                maximum: 100\n                                minimum: 0\n                                type: integer\n                            required:\n                            - backendRef\n                            type: object\n                            x-kubernetes-validations:\n                            - message: Only one of percent or fraction may be specified\n                                in HTTPRequestMirrorFilter\n                              rule: '!(has(self.percent) && has(self.fraction))'\n                          requestRedirect:\n                            description: |-\n                              RequestRedirect defines a schema for a filter that responds to the\n                              request with an HTTP redirection.\n\n                              Support: Core\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the hostname to be used in the value of the `Location`\n                                  header in the response.\n                                  When empty, the hostname in the `Host` header of the request is used.\n\n                                  Support: Core\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines parameters used to modify the path of the incoming request.\n                                  The modified path is then used to construct the `Location` header. When\n                                  empty, the request path is used as-is.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                              port:\n                                description: |-\n                                  Port is the port to be used in the value of the `Location`\n                                  header in the response.\n\n                                  If no port is specified, the redirect port MUST be derived using the\n                                  following rules:\n\n                                  * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                    port associated with the redirect scheme. Specifically \"http\" to port 80\n                                    and \"https\" to port 443. If the redirect scheme does not have a\n                                    well-known port, the listener port of the Gateway SHOULD be used.\n                                  * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                    Listener port.\n\n                                  Implementations SHOULD NOT add the port number in the 'Location'\n                                  header in the following cases:\n\n                                  * A Location header that will use HTTP (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 80.\n                                  * A Location header that will use HTTPS (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                  Support: Extended\n                                format: int32\n                                maximum: 65535\n                                minimum: 1\n                                type: integer\n                              scheme:\n                                description: |-\n                                  Scheme is the scheme to be used in the value of the `Location` header in\n                                  the response. When empty, the scheme of the request is used.\n\n                                  Scheme redirects can affect the port of the redirect, for more information,\n                                  refer to the documentation for the port field of this filter.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Extended\n                                enum:\n                                - http\n                                - https\n                                type: string\n                              statusCode:\n                                default: 302\n                                description: |-\n                                  StatusCode is the HTTP status code to be used in response.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Core\n                                enum:\n                                - 301\n                                - 302\n                                - 303\n                                - 307\n                                - 308\n                                type: integer\n                            type: object\n                          responseHeaderModifier:\n                            description: |-\n                              ResponseHeaderModifier defines a schema for a filter that modifies response\n                              headers.\n\n                              Support: Extended\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          type:\n                            description: |-\n                              Type identifies the type of filter to apply. As with other API fields,\n                              types are classified into three conformance levels:\n\n                              - Core: Filter types and their corresponding configuration defined by\n                                \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                implementations must support core filters.\n\n                              - Extended: Filter types and their corresponding configuration defined by\n                                \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                are encouraged to support extended filters.\n\n                              - Implementation-specific: Filters that are defined and supported by\n                                specific vendors.\n                                In the future, filters showing convergence in behavior across multiple\n                                implementations will be considered for inclusion in extended or core\n                                conformance levels. Filter-specific configuration for such filters\n                                is specified using the ExtensionRef field. `Type` should be set to\n                                \"ExtensionRef\" for custom filters.\n\n                              Implementers are encouraged to define custom implementation types to\n                              extend the core API with implementation-specific behavior.\n\n                              If a reference to a custom filter type cannot be resolved, the filter\n                              MUST NOT be skipped. Instead, requests that would have been processed by\n                              that filter MUST receive a HTTP error response.\n\n                              Note that values may be added to this enum, implementations\n                              must ensure that unknown values will not cause a crash.\n\n                              Unknown values here must result in the implementation setting the\n                              Accepted Condition for the Route to `status: False`, with a\n                              Reason of `UnsupportedValue`.\n                            enum:\n                            - RequestHeaderModifier\n                            - ResponseHeaderModifier\n                            - RequestMirror\n                            - RequestRedirect\n                            - URLRewrite\n                            - ExtensionRef\n                            - CORS\n                            - ExternalAuth\n                            type: string\n                          urlRewrite:\n                            description: |-\n                              URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                              Support: Extended\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the value to be used to replace the Host header value during\n                                  forwarding.\n\n                                  Support: Extended\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines a path rewrite.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                            type: object\n                        required:\n                        - type\n                        type: object\n                        x-kubernetes-validations:\n                        - message: filter.cors must be nil if the filter.type is not\n                            CORS\n                          rule: '!(has(self.cors) && self.type != ''CORS'')'\n                        - message: filter.cors must be specified for CORS filter.type\n                          rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                        - message: filter.requestHeaderModifier must be nil if the\n                            filter.type is not RequestHeaderModifier\n                          rule: '!(has(self.requestHeaderModifier) && self.type !=\n                            ''RequestHeaderModifier'')'\n                        - message: filter.requestHeaderModifier must be specified\n                            for RequestHeaderModifier filter.type\n                          rule: '!(!has(self.requestHeaderModifier) && self.type ==\n                            ''RequestHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be nil if the\n                            filter.type is not ResponseHeaderModifier\n                          rule: '!(has(self.responseHeaderModifier) && self.type !=\n                            ''ResponseHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be specified\n                            for ResponseHeaderModifier filter.type\n                          rule: '!(!has(self.responseHeaderModifier) && self.type\n                            == ''ResponseHeaderModifier'')'\n                        - message: filter.requestMirror must be nil if the filter.type\n                            is not RequestMirror\n                          rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                        - message: filter.requestMirror must be specified for RequestMirror\n                            filter.type\n                          rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'\n                        - message: filter.requestRedirect must be nil if the filter.type\n                            is not RequestRedirect\n                          rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')'\n                        - message: filter.requestRedirect must be specified for RequestRedirect\n                            filter.type\n                          rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')'\n                        - message: filter.urlRewrite must be nil if the filter.type\n                            is not URLRewrite\n                          rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                        - message: filter.urlRewrite must be specified for URLRewrite\n                            filter.type\n                          rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                        - message: filter.extensionRef must be nil if the filter.type\n                            is not ExtensionRef\n                          rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                        - message: filter.extensionRef must be specified for ExtensionRef\n                            filter.type\n                          rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                        - message: filter.externalAuth must be nil if the filter.type\n                            is not ExternalAuth\n                          rule: '!(has(self.externalAuth) && self.type != ''ExternalAuth'')'\n                        - message: filter.externalAuth must be specified for ExternalAuth\n                            filter.type\n                          rule: '!(!has(self.externalAuth) && self.type == ''ExternalAuth'')'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                      x-kubernetes-validations:\n                      - message: May specify either httpRouteFilterRequestRedirect\n                          or httpRouteFilterRequestRewrite, but not both\n                        rule: '!(self.exists(f, f.type == ''RequestRedirect'') &&\n                          self.exists(f, f.type == ''URLRewrite''))'\n                      - message: RequestHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                          <= 1\n                      - message: ResponseHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                          <= 1\n                      - message: RequestRedirect filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestRedirect').size() <=\n                          1\n                      - message: URLRewrite filter cannot be repeated\n                        rule: self.filter(f, f.type == 'URLRewrite').size() <= 1\n                    matches:\n                      default:\n                      - path:\n                          type: PathPrefix\n                          value: /\n                      description: |-\n                        Matches define conditions used for matching the rule against incoming\n                        HTTP requests. Each match is independent, i.e. this rule will be matched\n                        if **any** one of the matches is satisfied.\n\n                        For example, take the following matches configuration:\n\n                        ```\n                        matches:\n                        - path:\n                            value: \"/foo\"\n                          headers:\n                          - name: \"version\"\n                            value: \"v2\"\n                        - path:\n                            value: \"/v2/foo\"\n                        ```\n\n                        For a request to match against this rule, a request must satisfy\n                        EITHER of the two conditions:\n\n                        - path prefixed with `/foo` AND contains the header `version: v2`\n                        - path prefix of `/v2/foo`\n\n                        See the documentation for HTTPRouteMatch on how to specify multiple\n                        match conditions that should be ANDed together.\n\n                        If no matches are specified, the default is a prefix\n                        path match on \"/\", which has the effect of matching every\n                        HTTP request.\n\n                        Proxy or Load Balancer routing configuration generated from HTTPRoutes\n                        MUST prioritize matches based on the following criteria, continuing on\n                        ties. Across all rules specified on applicable Routes, precedence must be\n                        given to the match having:\n\n                        * \"Exact\" path match.\n                        * \"Prefix\" path match with largest number of characters.\n                        * Method match.\n                        * Largest number of header matches.\n                        * Largest number of query param matches.\n\n                        Note: The precedence of RegularExpression path matches are implementation-specific.\n\n                        If ties still exist across multiple Routes, matching precedence MUST be\n                        determined in order of the following criteria, continuing on ties:\n\n                        * The oldest Route based on creation timestamp.\n                        * The Route appearing first in alphabetical order by\n                          \"{namespace}/{name}\".\n\n                        If ties still exist within an HTTPRoute, matching precedence MUST be granted\n                        to the FIRST matching rule (in list order) with a match meeting the above\n                        criteria.\n\n                        When no rules matching a request have been successfully attached to the\n                        parent a request is coming from, a HTTP 404 status code MUST be returned.\n                      items:\n                        description: \"HTTPRouteMatch defines the predicate used to\n                          match requests to a given\\naction. Multiple match types\n                          are ANDed together, i.e. the match will\\nevaluate to true\n                          only if all conditions are satisfied.\\n\\nFor example, the\n                          match below will match a HTTP request only if its path\\nstarts\n                          with `/foo` AND it contains the `version: v1` header:\\n\\n```\\nmatch:\\n\\n\\tpath:\\n\\t\n                          \\ value: \\\"/foo\\\"\\n\\theaders:\\n\\t- name: \\\"version\\\"\\n\\t\n                          \\ value \\\"v1\\\"\\n\\n```\"\n                        properties:\n                          headers:\n                            description: |-\n                              Headers specifies HTTP request header matchers. Multiple match values are\n                              ANDed together, meaning, a request must match all the specified headers\n                              to select the route.\n                            items:\n                              description: |-\n                                HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request\n                                headers.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                    case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                    If multiple entries specify equivalent header names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent header name MUST be ignored. Due to the\n                                    case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                    equivalent.\n\n                                    When a header is repeated in an HTTP request, it is\n                                    implementation-specific behavior as to how this is represented.\n                                    Generally, proxies should follow the guidance from the RFC:\n                                    https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding\n                                    processing a repeated header, with special handling for \"Set-Cookie\".\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the header.\n\n                                    Support: Core (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression HeaderMatchType has implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other dialects\n                                    of regular expressions. Please read the implementation's documentation to\n                                    determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: |-\n                                    Value is the value of HTTP Header to be matched.\n\n                                    Must consist of printable US-ASCII characters, optionally separated\n                                    by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                  maxLength: 4096\n                                  minLength: 1\n                                  pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                          method:\n                            description: |-\n                              Method specifies HTTP method matcher.\n                              When specified, this route will be matched only if the request has the\n                              specified method.\n\n                              Support: Extended\n                            enum:\n                            - GET\n                            - HEAD\n                            - POST\n                            - PUT\n                            - DELETE\n                            - CONNECT\n                            - OPTIONS\n                            - TRACE\n                            - PATCH\n                            type: string\n                          path:\n                            default:\n                              type: PathPrefix\n                              value: /\n                            description: |-\n                              Path specifies a HTTP request path matcher. If this field is not\n                              specified, a default prefix match on the \"/\" path is provided.\n                            properties:\n                              type:\n                                default: PathPrefix\n                                description: |-\n                                  Type specifies how to match against the path Value.\n\n                                  Support: Core (Exact, PathPrefix)\n\n                                  Support: Implementation-specific (RegularExpression)\n                                enum:\n                                - Exact\n                                - PathPrefix\n                                - RegularExpression\n                                type: string\n                              value:\n                                default: /\n                                description: Value of the HTTP path to match against.\n                                maxLength: 1024\n                                type: string\n                            type: object\n                            x-kubernetes-validations:\n                            - message: value must be an absolute path and start with\n                                '/' when type one of ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'')\n                                : true'\n                            - message: must not contain '//' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'')\n                                : true'\n                            - message: must not contain '/./' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'')\n                                : true'\n                            - message: must not contain '/../' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'')\n                                : true'\n                            - message: must not contain '%2f' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'')\n                                : true'\n                            - message: must not contain '%2F' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'')\n                                : true'\n                            - message: must not contain '#' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'')\n                                : true'\n                            - message: must not end with '/..' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'')\n                                : true'\n                            - message: must not end with '/.' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'')\n                                : true'\n                            - message: type must be one of ['Exact', 'PathPrefix',\n                                'RegularExpression']\n                              rule: self.type in ['Exact','PathPrefix'] || self.type\n                                == 'RegularExpression'\n                            - message: must only contain valid characters (matching\n                                ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$)\n                                for types ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r\"\"\"^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$\"\"\")\n                                : true'\n                          queryParams:\n                            description: |-\n                              QueryParams specifies HTTP query parameter matchers. Multiple match\n                              values are ANDed together, meaning, a request must match all the\n                              specified query parameters to select the route.\n\n                              Support: Extended\n                            items:\n                              description: |-\n                                HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP\n                                query parameters.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP query param to be matched. This must be an\n                                    exact string match. (See\n                                    https://tools.ietf.org/html/rfc7230#section-2.7.3).\n\n                                    If multiple entries specify equivalent query param names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent query param name MUST be ignored.\n\n                                    If a query param is repeated in an HTTP request, the behavior is\n                                    purposely left undefined, since different data planes have different\n                                    capabilities. However, it is *recommended* that implementations should\n                                    match against the first value of the param if the data plane supports it,\n                                    as this behavior is expected in other load balancing contexts outside of\n                                    the Gateway API.\n\n                                    Users SHOULD NOT route traffic based on repeated query params to guard\n                                    themselves against potential differences in the implementations.\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the query parameter.\n\n                                    Support: Extended (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression QueryParamMatchType has Implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other\n                                    dialects of regular expressions. Please read the implementation's\n                                    documentation to determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of HTTP query param\n                                    to be matched.\n                                  maxLength: 1024\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                        type: object\n                      maxItems: 64\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    retry:\n                      description: |-\n                        Retry defines the configuration for when to retry an HTTP request.\n\n                        Support: Extended\n                      properties:\n                        attempts:\n                          description: |-\n                            Attempts specifies the maximum number of times an individual request\n                            from the gateway to a backend should be retried.\n\n                            If the maximum number of retries has been attempted without a successful\n                            response from the backend, the Gateway MUST return an error.\n\n                            When this field is unspecified, the number of times to attempt to retry\n                            a backend request is implementation-specific.\n\n                            Support: Extended\n                          type: integer\n                        backoff:\n                          description: |-\n                            Backoff specifies the minimum duration a Gateway should wait between\n                            retry attempts and is represented in Gateway API Duration formatting.\n\n                            For example, setting the `rules[].retry.backoff` field to the value\n                            `100ms` will cause a backend request to first be retried approximately\n                            100 milliseconds after timing out or receiving a response code configured\n                            to be retriable.\n\n                            An implementation MAY use an exponential or alternative backoff strategy\n                            for subsequent retry attempts, MAY cap the maximum backoff duration to\n                            some amount greater than the specified minimum, and MAY add arbitrary\n                            jitter to stagger requests, as long as unsuccessful backend requests are\n                            not retried before the configured minimum duration.\n\n                            If a Request timeout (`rules[].timeouts.request`) is configured on the\n                            route, the entire duration of the initial request and any retry attempts\n                            MUST not exceed the Request timeout duration. If any retry attempts are\n                            still in progress when the Request timeout duration has been reached,\n                            these SHOULD be canceled if possible and the Gateway MUST immediately\n                            return a timeout error.\n\n                            If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is\n                            configured on the route, any retry attempts which reach the configured\n                            BackendRequest timeout duration without a response SHOULD be canceled if\n                            possible and the Gateway should wait for at least the specified backoff\n                            duration before attempting to retry the backend request again.\n\n                            If a BackendRequest timeout is _not_ configured on the route, retry\n                            attempts MAY time out after an implementation default duration, or MAY\n                            remain pending until a configured Request timeout or implementation\n                            default duration for total request time is reached.\n\n                            When this field is unspecified, the time to wait between retry attempts\n                            is implementation-specific.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        codes:\n                          description: |-\n                            Codes defines the HTTP response status codes for which a backend request\n                            should be retried.\n\n                            Support: Extended\n                          items:\n                            description: |-\n                              HTTPRouteRetryStatusCode defines an HTTP response status code for\n                              which a backend request should be retried.\n\n                              Implementations MUST support the following status codes as retriable:\n\n                              * 500\n                              * 502\n                              * 503\n                              * 504\n\n                              Implementations MAY support specifying additional discrete values in the\n                              500-599 range.\n\n                              Implementations MAY support specifying discrete values in the 400-499 range,\n                              which are often inadvisable to retry.\n                            maximum: 599\n                            minimum: 400\n                            type: integer\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    sessionPersistence:\n                      description: |-\n                        SessionPersistence defines and configures session persistence\n                        for the route rule.\n\n                        Support: Extended\n                      properties:\n                        absoluteTimeout:\n                          description: |-\n                            AbsoluteTimeout defines the absolute timeout of the persistent\n                            session. Once the AbsoluteTimeout duration has elapsed, the\n                            session becomes invalid.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        cookieConfig:\n                          description: |-\n                            CookieConfig provides configuration settings that are specific\n                            to cookie-based session persistence.\n\n                            Support: Core\n                          properties:\n                            lifetimeType:\n                              default: Session\n                              description: |-\n                                LifetimeType specifies whether the cookie has a permanent or\n                                session-based lifetime. A permanent cookie persists until its\n                                specified expiry time, defined by the Expires or Max-Age cookie\n                                attributes, while a session cookie is deleted when the current\n                                session ends.\n\n                                When set to \"Permanent\", AbsoluteTimeout indicates the\n                                cookie's lifetime via the Expires or Max-Age cookie attributes\n                                and is required.\n\n                                When set to \"Session\", AbsoluteTimeout indicates the\n                                absolute lifetime of the cookie tracked by the gateway and\n                                is optional.\n\n                                Defaults to \"Session\".\n\n                                Support: Core for \"Session\" type\n\n                                Support: Extended for \"Permanent\" type\n                              enum:\n                              - Permanent\n                              - Session\n                              type: string\n                          type: object\n                        idleTimeout:\n                          description: |-\n                            IdleTimeout defines the idle timeout of the persistent session.\n                            Once the session has been idle for more than the specified\n                            IdleTimeout duration, the session becomes invalid.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        sessionName:\n                          description: |-\n                            SessionName defines the name of the persistent session token\n                            which may be reflected in the cookie or the header. Users\n                            should avoid reusing session names to prevent unintended\n                            consequences, such as rejection or unpredictable behavior.\n\n                            Support: Implementation-specific\n                          maxLength: 128\n                          type: string\n                        type:\n                          default: Cookie\n                          description: |-\n                            Type defines the type of session persistence such as through\n                            the use of a header or cookie. Defaults to cookie based session\n                            persistence.\n\n                            Support: Core for \"Cookie\" type\n\n                            Support: Extended for \"Header\" type\n                          enum:\n                          - Cookie\n                          - Header\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: AbsoluteTimeout must be specified when cookie lifetimeType\n                          is Permanent\n                        rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)\n                          || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'\n                      - message: cookieConfig can only be set with type Cookie\n                        rule: '!has(self.cookieConfig) || self.type == ''Cookie'''\n                    timeouts:\n                      description: |-\n                        Timeouts defines the timeouts that can be configured for an HTTP request.\n\n                        Support: Extended\n                      properties:\n                        backendRequest:\n                          description: |-\n                            BackendRequest specifies a timeout for an individual request from the gateway\n                            to a backend. This covers the time from when the request first starts being\n                            sent from the gateway to when the full response has been received from the backend.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            An entire client HTTP transaction with a gateway, covered by the Request timeout,\n                            may result in more than one call from the gateway to the destination backend,\n                            for example, if automatic retries are supported.\n\n                            The value of BackendRequest must be a Gateway API Duration string as defined by\n                            GEP-2257.  When this field is unspecified, its behavior is implementation-specific;\n                            when specified, the value of BackendRequest must be no more than the value of the\n                            Request timeout (since the Request timeout encompasses the BackendRequest timeout).\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        request:\n                          description: |-\n                            Request specifies the maximum duration for a gateway to respond to an HTTP request.\n                            If the gateway has not been able to respond before this deadline is met, the gateway\n                            MUST return a timeout error.\n\n                            For example, setting the `rules.timeouts.request` field to the value `10s` in an\n                            `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds\n                            to complete.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            This timeout is intended to cover as close to the whole request-response transaction\n                            as possible although an implementation MAY choose to start the timeout after the entire\n                            request stream has been received instead of immediately after the transaction is\n                            initiated by the client.\n\n                            The value of Request is a Gateway API Duration string as defined by GEP-2257. When this\n                            field is unspecified, request timeout behavior is implementation-specific.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: backendRequest timeout cannot be longer than request\n                          timeout\n                        rule: '!(has(self.request) && has(self.backendRequest) &&\n                          duration(self.request) != duration(''0s'') && duration(self.backendRequest)\n                          > duration(self.request))'\n                  type: object\n                  x-kubernetes-validations:\n                  - message: RequestRedirect filter must not be used together with\n                      backendRefs\n                    rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ?\n                      (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))):\n                      true'\n                  - message: When using RequestRedirect filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      ? ((size(self.matches) != 1 || !has(self.matches[0].path) ||\n                      self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: When using URLRewrite filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                  - message: Within backendRefs, when using RequestRedirect filter\n                      with path.replacePrefixMatch, exactly one PathPrefix match must\n                      be specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      )) ? ((size(self.matches) != 1 || !has(self.matches[0].path)\n                      || self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: Within backendRefs, When using URLRewrite filter with\n                      path.replacePrefixMatch, exactly one PathPrefix match must be\n                      specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: While 16 rules and 64 matches per rule are allowed, the\n                    total number of matches across all rules in a route must be less\n                    than 128\n                  rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size()\n                    > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size()\n                    : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size()\n                    > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size()\n                    : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size()\n                    > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size()\n                    : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size()\n                    > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size()\n                    : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size()\n                    > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size()\n                    : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128'\n                - message: Rule name must be unique within the route\n                  rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)\n                    && l1.name == l2.name))\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            type: object\n          status:\n            description: Status defines the current state of HTTPRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .spec.hostnames\n      name: Hostnames\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          HTTPRoute provides a way to route HTTP requests. This includes the capability\n          to match requests by hostname, path, header, or query param. Filters can be\n          used to specify additional processing steps. Backends specify where matching\n          requests should be routed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of HTTPRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of hostnames that should match against the HTTP Host\n                  header to select a HTTPRoute used to process the request. Implementations\n                  MUST ignore any port value specified in the HTTP Host header while\n                  performing a match and (absent of any applicable header modification\n                  configuration) MUST forward this header unmodified to the backend.\n\n                  Valid values for Hostnames are determined by RFC 1123 definition of a\n                  hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and HTTPRoute, there\n                  must be at least one intersecting hostname for the HTTPRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `*.example.com`, `test.example.com`, and `foo.test.example.com` would\n                    all match. On the other hand, `example.com` and `test.example.net` would\n                    not match.\n\n                  Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                  as a suffix match. That means that a match for `*.example.com` would match\n                  both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                  If both the Listener and HTTPRoute have specified hostnames, any\n                  HTTPRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  HTTPRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` must not be considered for a match.\n\n                  If both the Listener and HTTPRoute have specified hostnames, and none\n                  match with the criteria above, then the HTTPRoute is not accepted. The\n                  implementation must raise an 'Accepted' Condition with a status of\n                  `False` in the corresponding RouteParentStatus.\n\n                  In the event that multiple HTTPRoutes specify intersecting hostnames (e.g.\n                  overlapping wildcard matching and exact matching hostnames), precedence must\n                  be given to rules from the HTTPRoute with the largest number of:\n\n                  * Characters in a matching non-wildcard hostname.\n                  * Characters in a matching hostname.\n\n                  If ties exist across multiple Routes, the matching precedence rules for\n                  HTTPRouteMatches takes over.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                default:\n                - matches:\n                  - path:\n                      type: PathPrefix\n                      value: /\n                description: Rules are a list of HTTP matchers, filters and actions.\n                items:\n                  description: |-\n                    HTTPRouteRule defines semantics for matching an HTTP request based on\n                    conditions (matches), processing it (filters), and forwarding the request to\n                    an API object (backendRefs).\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent.\n\n                        Failure behavior here depends on how many BackendRefs are specified and\n                        how many are invalid.\n\n                        If *all* entries in BackendRefs are invalid, and there are also no filters\n                        specified in this route rule, *all* traffic which matches this rule MUST\n                        receive a 500 status code.\n\n                        See the HTTPBackendRef definition for the rules about what makes a single\n                        HTTPBackendRef invalid.\n\n                        When a HTTPBackendRef is invalid, 500 status codes MUST be returned for\n                        requests that would have otherwise been routed to an invalid backend. If\n                        multiple backends are specified, and some are invalid, the proportion of\n                        requests that would otherwise have been routed to an invalid backend\n                        MUST receive a 500 status code.\n\n                        For example, if two backends are specified with equal weights, and one is\n                        invalid, 50 percent of traffic must receive a 500. Implementations may\n                        choose how that 50 percent is determined.\n\n                        When a HTTPBackendRef refers to a Service that has no ready endpoints,\n                        implementations SHOULD return a 503 for requests to that backend instead.\n                        If an implementation chooses to do this, all of the above rules for 500 responses\n                        MUST also apply for responses that return a 503.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Core\n                      items:\n                        description: |-\n                          HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n                        properties:\n                          filters:\n                            description: |-\n                              Filters defined at this level should be executed if and only if the\n                              request is being forwarded to the backend defined here.\n\n                              Support: Implementation-specific (For broader support of filters, use the\n                              Filters field in HTTPRouteRule.)\n                            items:\n                              description: |-\n                                HTTPRouteFilter defines processing steps that must be completed during the\n                                request or response lifecycle. HTTPRouteFilters are meant as an extension\n                                point to express processing that may be done in Gateway implementations. Some\n                                examples include request or response modification, implementing\n                                authentication strategies, rate-limiting, and traffic shaping. API\n                                guarantee/conformance is defined based on the type of the filter.\n                              properties:\n                                cors:\n                                  description: |-\n                                    CORS defines a schema for a filter that responds to the\n                                    cross-origin request based on HTTP response header.\n\n                                    Support: Extended\n                                  properties:\n                                    allowCredentials:\n                                      description: |-\n                                        AllowCredentials indicates whether the actual cross-origin request allows\n                                        to include credentials.\n\n                                        When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                        response header with value true (case-sensitive).\n\n                                        When set to false or omitted the gateway will omit the header\n                                        `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                        behavior).\n\n                                        Support: Extended\n                                      type: boolean\n                                    allowHeaders:\n                                      description: |-\n                                        AllowHeaders indicates which HTTP request headers are supported for\n                                        accessing the requested resource.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        When the `AllowHeaders` field is configured with one or more headers, the\n                                        gateway must return the `Access-Control-Allow-Headers` response header\n                                        which value is present in the `AllowHeaders` field.\n\n                                        If any header name in the `Access-Control-Request-Headers` request header\n                                        is not included in the list of header names specified by the response\n                                        header `Access-Control-Allow-Headers`, it will present an error on the\n                                        client side.\n\n                                        If any header name in the `Access-Control-Allow-Headers` response header\n                                        does not recognize by the client, it will also occur an error on the\n                                        client side.\n\n                                        A wildcard indicates that the requests with all HTTP headers are allowed.\n                                        If config contains the wildcard \"*\" in allowHeaders and the request is\n                                        not credentialed, the `Access-Control-Allow-Headers` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Headers from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Headers` response header. When\n                                        also the `AllowCredentials` field is true and `AllowHeaders` field\n                                        is specified with the `*` wildcard, the gateway must specify one or more\n                                        HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                        header. The value of the header `Access-Control-Allow-Headers` is same as\n                                        the `Access-Control-Request-Headers` header provided by the client. If\n                                        the header `Access-Control-Request-Headers` is not included in the\n                                        request, the gateway will omit the `Access-Control-Allow-Headers`\n                                        response header, instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowHeaders cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowMethods:\n                                      description: |-\n                                        AllowMethods indicates which HTTP methods are supported for accessing the\n                                        requested resource.\n\n                                        Valid values are any method defined by RFC9110, along with the special\n                                        value `*`, which represents all HTTP methods are allowed.\n\n                                        Method names are case-sensitive, so these values are also case-sensitive.\n                                        (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                        Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                        response header are separated by a comma (\",\").\n\n                                        A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                        CORS-safelisted methods are always allowed, regardless of whether they\n                                        are specified in the `AllowMethods` field.\n\n                                        When the `AllowMethods` field is configured with one or more methods, the\n                                        gateway must return the `Access-Control-Allow-Methods` response header\n                                        which value is present in the `AllowMethods` field.\n\n                                        If the HTTP method of the `Access-Control-Request-Method` request header\n                                        is not included in the list of methods specified by the response header\n                                        `Access-Control-Allow-Methods`, it will present an error on the client\n                                        side.\n\n                                        If config contains the wildcard \"*\" in allowMethods and the request is\n                                        not credentialed, the `Access-Control-Allow-Methods` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Method from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Methods` response header. When\n                                        also the `AllowCredentials` field is true and `AllowMethods` field\n                                        specified with the `*` wildcard, the gateway must specify one HTTP method\n                                        in the value of the Access-Control-Allow-Methods response header. The\n                                        value of the header `Access-Control-Allow-Methods` is same as the\n                                        `Access-Control-Request-Method` header provided by the client. If the\n                                        header `Access-Control-Request-Method` is not included in the request,\n                                        the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                        instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        enum:\n                                        - GET\n                                        - HEAD\n                                        - POST\n                                        - PUT\n                                        - DELETE\n                                        - CONNECT\n                                        - OPTIONS\n                                        - TRACE\n                                        - PATCH\n                                        - '*'\n                                        type: string\n                                      maxItems: 9\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowMethods cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowOrigins:\n                                      description: |-\n                                        AllowOrigins indicates whether the response can be shared with requested\n                                        resource from the given `Origin`.\n\n                                        The `Origin` consists of a scheme and a host, with an optional port, and\n                                        takes the form `<scheme>://<host>(:<port>)`.\n\n                                        Valid values for scheme are: `http` and `https`.\n\n                                        Valid values for port are any integer between 1 and 65535 (the list of\n                                        available TCP/UDP ports). Note that, if not included, port `80` is\n                                        assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                        origins. This may affect origin matching.\n\n                                        The host part of the origin may contain the wildcard character `*`. These\n                                        wildcard characters behave as follows:\n\n                                        * `*` is a greedy match to the _left_, including any number of\n                                          DNS labels to the left of its position. This also means that\n                                          `*` will include any number of period `.` characters to the\n                                          left of its position.\n                                        * A wildcard by itself matches all hosts.\n\n                                        An origin value that includes _only_ the `*` character indicates requests\n                                        from all `Origin`s are allowed.\n\n                                        When the `AllowOrigins` field is configured with multiple origins, it\n                                        means the server supports clients from multiple origins. If the request\n                                        `Origin` matches the configured allowed origins, the gateway must return\n                                        the given `Origin` and sets value of the header\n                                        `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                        client.\n\n                                        The status code of a successful response to a \"preflight\" request is\n                                        always an OK status (i.e., 204 or 200).\n\n                                        If the request `Origin` does not match the configured allowed origins,\n                                        the gateway returns 204/200 response but doesn't set the relevant\n                                        cross-origin response headers. Alternatively, the gateway responds with\n                                        403 status to the \"preflight\" request is denied, coupled with omitting\n                                        the CORS headers. The cross-origin request fails on the client side.\n                                        Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                        Conversely, if the request `Origin` matches one of the configured\n                                        allowed origins, the gateway sets the response header\n                                        `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                        header provided by the client.\n\n                                        When config has the wildcard (\"*\") in allowOrigins, and the request\n                                        is not credentialed (e.g., it is a preflight request), the\n                                        `Access-Control-Allow-Origin` response header either contains the\n                                        wildcard as well or the Origin from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Origin` response header. When\n                                        also the `AllowCredentials` field is true and `AllowOrigins` field\n                                        specified with the `*` wildcard, the gateway must return a single origin\n                                        in the value of the `Access-Control-Allow-Origin` response header,\n                                        instead of specifying the `*` wildcard. The value of the header\n                                        `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                        the client.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                          encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                          scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                          URIs that include an authority MUST include a fully qualified domain name or\n                                          IP address as the host.\n                                        maxLength: 253\n                                        minLength: 1\n                                        pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowOrigins cannot contain '*' alongside\n                                          other origins\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    exposeHeaders:\n                                      description: |-\n                                        ExposeHeaders indicates which HTTP response headers can be exposed\n                                        to client-side scripts in response to a cross-origin request.\n\n                                        A CORS-safelisted response header is an HTTP header in a CORS response\n                                        that it is considered safe to expose to the client scripts.\n                                        The CORS-safelisted response headers include the following headers:\n                                        `Cache-Control`\n                                        `Content-Language`\n                                        `Content-Length`\n                                        `Content-Type`\n                                        `Expires`\n                                        `Last-Modified`\n                                        `Pragma`\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                        The CORS-safelisted response headers are exposed to client by default.\n\n                                        When an HTTP header name is specified using the `ExposeHeaders` field,\n                                        this additional header will be exposed as part of the response to the\n                                        client.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        A wildcard indicates that the responses with all HTTP headers are exposed\n                                        to clients. The `Access-Control-Expose-Headers` response header can only\n                                        use `*` wildcard as value when the request is not credentialed.\n\n                                        When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                        the request is credentialed, the gateway cannot use the `*` wildcard in\n                                        the `Access-Control-Expose-Headers` response header.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    maxAge:\n                                      default: 5\n                                      description: |-\n                                        MaxAge indicates the duration (in seconds) for the client to cache the\n                                        results of a \"preflight\" request.\n\n                                        The information provided by the `Access-Control-Allow-Methods` and\n                                        `Access-Control-Allow-Headers` response headers can be cached by the\n                                        client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                        The default value of `Access-Control-Max-Age` response header is 5\n                                        (seconds).\n\n                                        When the `MaxAge` field is unspecified, the gateway sets the response\n                                        header \"Access-Control-Max-Age: 5\" by default.\n                                      format: int32\n                                      minimum: 1\n                                      type: integer\n                                  type: object\n                                extensionRef:\n                                  description: |-\n                                    ExtensionRef is an optional, implementation-specific extension to the\n                                    \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                                    \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                                    extended filters.\n\n                                    This filter can be used multiple times within the same rule.\n\n                                    Support: Implementation-specific\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When unspecified or empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"HTTPRoute\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                externalAuth:\n                                  description: |-\n                                    ExternalAuth configures settings related to sending request details\n                                    to an external auth service. The external service MUST authenticate\n                                    the request, and MAY authorize the request as well.\n\n                                    If there is any problem communicating with the external service,\n                                    this filter MUST fail closed.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef is a reference to a backend to send authorization\n                                        requests to.\n\n                                        The backend must speak the selected protocol (GRPC or HTTP) on the\n                                        referenced port.\n\n                                        If the backend service requires TLS, use BackendTLSPolicy to tell the\n                                        implementation to supply the TLS details to be used to connect to that\n                                        backend.\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    forwardBody:\n                                      description: |-\n                                        ForwardBody controls if requests to the authorization server should include\n                                        the body of the client request; and if so, how big that body is allowed\n                                        to be.\n\n                                        It is expected that implementations will buffer the request body up to\n                                        `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n                                        4xx series error (413 or 403 are common examples), and fail processing\n                                        of the filter.\n\n                                        If unset, or `forwardBody.maxSize` is set to `0`, then the body will not\n                                        be forwarded.\n\n                                        Feature Name: HTTPRouteExternalAuthForwardBody\n                                      properties:\n                                        maxSize:\n                                          description: |-\n                                            MaxSize specifies how large in bytes the largest body that will be buffered\n                                            and sent to the authorization server. If the body size is larger than\n                                            `maxSize`, then the body sent to the authorization server must be\n                                            truncated to `maxSize` bytes.\n\n                                            Experimental note: This behavior needs to be checked against\n                                            various dataplanes; it may need to be changed.\n                                            See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\n                                            for more.\n\n                                            If 0, the body will not be sent to the authorization server.\n                                          type: integer\n                                      type: object\n                                    grpc:\n                                      description: |-\n                                        GRPCAuthConfig contains configuration for communication with ext_authz\n                                        protocol-speaking backends.\n\n                                        If unset, implementations must assume the default behavior for each\n                                        included field is intended.\n                                      properties:\n                                        allowedHeaders:\n                                          description: |-\n                                            AllowedRequestHeaders specifies what headers from the client request\n                                            will be sent to the authorization server.\n\n                                            If this list is empty, then all headers must be sent.\n\n                                            If the list has entries, only those entries must be sent.\n                                          items:\n                                            type: string\n                                          maxItems: 64\n                                          type: array\n                                          x-kubernetes-list-type: set\n                                      type: object\n                                    http:\n                                      description: |-\n                                        HTTPAuthConfig contains configuration for communication with HTTP-speaking\n                                        backends.\n\n                                        If unset, implementations must assume the default behavior for each\n                                        included field is intended.\n                                      properties:\n                                        allowedHeaders:\n                                          description: |-\n                                            AllowedRequestHeaders specifies what additional headers from the client request\n                                            will be sent to the authorization server.\n\n                                            The following headers must always be sent to the authorization server,\n                                            regardless of this setting:\n\n                                            * `Host`\n                                            * `Method`\n                                            * `Path`\n                                            * `Content-Length`\n                                            * `Authorization`\n\n                                            If this list is empty, then only those headers must be sent.\n\n                                            Note that `Content-Length` has a special behavior, in that the length\n                                            sent must be correct for the actual request to the external authorization\n                                            server - that is, it must reflect the actual number of bytes sent in the\n                                            body of the request to the authorization server.\n\n                                            So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\n                                            to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\n                                            to anything other than `0`, then the `Content-Length` of the authorization\n                                            request must be set to the actual number of bytes forwarded.\n                                          items:\n                                            type: string\n                                          maxItems: 64\n                                          type: array\n                                          x-kubernetes-list-type: set\n                                        allowedResponseHeaders:\n                                          description: |-\n                                            AllowedResponseHeaders specifies what headers from the authorization response\n                                            will be copied into the request to the backend.\n\n                                            If this list is empty, then all headers from the authorization server\n                                            except Authority or Host must be copied.\n                                          items:\n                                            type: string\n                                          maxItems: 64\n                                          type: array\n                                          x-kubernetes-list-type: set\n                                        path:\n                                          description: |-\n                                            Path sets the prefix that paths from the client request will have added\n                                            when forwarded to the authorization server.\n\n                                            When empty or unspecified, no prefix is added.\n\n                                            Valid values are the same as the \"value\" regex for path values in the `match`\n                                            stanza, and the validation regex will screen out invalid paths in the same way.\n                                            Even with the validation, implementations MUST sanitize this input before using it\n                                            directly.\n                                          maxLength: 1024\n                                          pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$\n                                          type: string\n                                      type: object\n                                    protocol:\n                                      description: |-\n                                        ExternalAuthProtocol describes which protocol to use when communicating with an\n                                        ext_authz authorization server.\n\n                                        When this is set to GRPC, each backend must use the Envoy ext_authz protocol\n                                        on the port specified in `backendRefs`. Requests and responses are defined\n                                        in the protobufs explained at:\n                                        https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\n                                        When this is set to HTTP, each backend must respond with a `200` status\n                                        code in on a successful authorization. Any other code is considered\n                                        an authorization failure.\n\n                                        Feature Names:\n                                        GRPC Support - HTTPRouteExternalAuthGRPC\n                                        HTTP Support - HTTPRouteExternalAuthHTTP\n                                      enum:\n                                      - HTTP\n                                      - GRPC\n                                      type: string\n                                  required:\n                                  - backendRef\n                                  - protocol\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: grpc must be specified when protocol\n                                      is set to 'GRPC'\n                                    rule: 'self.protocol == ''GRPC'' ? has(self.grpc)\n                                      : true'\n                                  - message: protocol must be 'GRPC' when grpc is\n                                      set\n                                    rule: 'has(self.grpc) ? self.protocol == ''GRPC''\n                                      : true'\n                                  - message: http must be specified when protocol\n                                      is set to 'HTTP'\n                                    rule: 'self.protocol == ''HTTP'' ? has(self.http)\n                                      : true'\n                                  - message: protocol must be 'HTTP' when http is\n                                      set\n                                    rule: 'has(self.http) ? self.protocol == ''HTTP''\n                                      : true'\n                                requestHeaderModifier:\n                                  description: |-\n                                    RequestHeaderModifier defines a schema for a filter that modifies request\n                                    headers.\n\n                                    Support: Core\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                requestMirror:\n                                  description: |-\n                                    RequestMirror defines a schema for a filter that mirrors requests.\n                                    Requests are sent to the specified destination, but responses from\n                                    that destination are ignored.\n\n                                    This filter can be used multiple times within the same rule. Note that\n                                    not all implementations will be able to support mirroring to multiple\n                                    backends.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef references a resource where mirrored requests are sent.\n\n                                        Mirrored requests must be sent only to a single destination endpoint\n                                        within this BackendRef, irrespective of how many endpoints are present\n                                        within this BackendRef.\n\n                                        If the referent cannot be found, this BackendRef is invalid and must be\n                                        dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                        condition on the Route status is set to `status: False` and not configure\n                                        this backend in the underlying implementation.\n\n                                        If there is a cross-namespace reference to an *existing* object\n                                        that is not allowed by a ReferenceGrant, the controller must ensure the\n                                        \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                        with the \"RefNotPermitted\" reason and not configure this backend in the\n                                        underlying implementation.\n\n                                        In either error case, the Message of the `ResolvedRefs` Condition\n                                        should be used to provide more detail about the problem.\n\n                                        Support: Extended for Kubernetes Service\n\n                                        Support: Implementation-specific for any other resource\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    fraction:\n                                      description: |-\n                                        Fraction represents the fraction of requests that should be\n                                        mirrored to BackendRef.\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      properties:\n                                        denominator:\n                                          default: 100\n                                          format: int32\n                                          minimum: 1\n                                          type: integer\n                                        numerator:\n                                          format: int32\n                                          minimum: 0\n                                          type: integer\n                                      required:\n                                      - numerator\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: numerator must be less than or equal\n                                          to denominator\n                                        rule: self.numerator <= self.denominator\n                                    percent:\n                                      description: |-\n                                        Percent represents the percentage of requests that should be\n                                        mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                        requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      format: int32\n                                      maximum: 100\n                                      minimum: 0\n                                      type: integer\n                                  required:\n                                  - backendRef\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: Only one of percent or fraction may be\n                                      specified in HTTPRequestMirrorFilter\n                                    rule: '!(has(self.percent) && has(self.fraction))'\n                                requestRedirect:\n                                  description: |-\n                                    RequestRedirect defines a schema for a filter that responds to the\n                                    request with an HTTP redirection.\n\n                                    Support: Core\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the hostname to be used in the value of the `Location`\n                                        header in the response.\n                                        When empty, the hostname in the `Host` header of the request is used.\n\n                                        Support: Core\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines parameters used to modify the path of the incoming request.\n                                        The modified path is then used to construct the `Location` header. When\n                                        empty, the request path is used as-is.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                    port:\n                                      description: |-\n                                        Port is the port to be used in the value of the `Location`\n                                        header in the response.\n\n                                        If no port is specified, the redirect port MUST be derived using the\n                                        following rules:\n\n                                        * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                          port associated with the redirect scheme. Specifically \"http\" to port 80\n                                          and \"https\" to port 443. If the redirect scheme does not have a\n                                          well-known port, the listener port of the Gateway SHOULD be used.\n                                        * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                          Listener port.\n\n                                        Implementations SHOULD NOT add the port number in the 'Location'\n                                        header in the following cases:\n\n                                        * A Location header that will use HTTP (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 80.\n                                        * A Location header that will use HTTPS (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                        Support: Extended\n                                      format: int32\n                                      maximum: 65535\n                                      minimum: 1\n                                      type: integer\n                                    scheme:\n                                      description: |-\n                                        Scheme is the scheme to be used in the value of the `Location` header in\n                                        the response. When empty, the scheme of the request is used.\n\n                                        Scheme redirects can affect the port of the redirect, for more information,\n                                        refer to the documentation for the port field of this filter.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Extended\n                                      enum:\n                                      - http\n                                      - https\n                                      type: string\n                                    statusCode:\n                                      default: 302\n                                      description: |-\n                                        StatusCode is the HTTP status code to be used in response.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Core\n                                      enum:\n                                      - 301\n                                      - 302\n                                      - 303\n                                      - 307\n                                      - 308\n                                      type: integer\n                                  type: object\n                                responseHeaderModifier:\n                                  description: |-\n                                    ResponseHeaderModifier defines a schema for a filter that modifies response\n                                    headers.\n\n                                    Support: Extended\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: |-\n                                              Value is the value of HTTP Header to be matched.\n\n                                              Must consist of printable US-ASCII characters, optionally separated\n                                              by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                            maxLength: 4096\n                                            minLength: 1\n                                            pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                type:\n                                  description: |-\n                                    Type identifies the type of filter to apply. As with other API fields,\n                                    types are classified into three conformance levels:\n\n                                    - Core: Filter types and their corresponding configuration defined by\n                                      \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                      implementations must support core filters.\n\n                                    - Extended: Filter types and their corresponding configuration defined by\n                                      \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                      are encouraged to support extended filters.\n\n                                    - Implementation-specific: Filters that are defined and supported by\n                                      specific vendors.\n                                      In the future, filters showing convergence in behavior across multiple\n                                      implementations will be considered for inclusion in extended or core\n                                      conformance levels. Filter-specific configuration for such filters\n                                      is specified using the ExtensionRef field. `Type` should be set to\n                                      \"ExtensionRef\" for custom filters.\n\n                                    Implementers are encouraged to define custom implementation types to\n                                    extend the core API with implementation-specific behavior.\n\n                                    If a reference to a custom filter type cannot be resolved, the filter\n                                    MUST NOT be skipped. Instead, requests that would have been processed by\n                                    that filter MUST receive a HTTP error response.\n\n                                    Note that values may be added to this enum, implementations\n                                    must ensure that unknown values will not cause a crash.\n\n                                    Unknown values here must result in the implementation setting the\n                                    Accepted Condition for the Route to `status: False`, with a\n                                    Reason of `UnsupportedValue`.\n                                  enum:\n                                  - RequestHeaderModifier\n                                  - ResponseHeaderModifier\n                                  - RequestMirror\n                                  - RequestRedirect\n                                  - URLRewrite\n                                  - ExtensionRef\n                                  - CORS\n                                  - ExternalAuth\n                                  type: string\n                                urlRewrite:\n                                  description: |-\n                                    URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                                    Support: Extended\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the value to be used to replace the Host header value during\n                                        forwarding.\n\n                                        Support: Extended\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines a path rewrite.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                  type: object\n                              required:\n                              - type\n                              type: object\n                              x-kubernetes-validations:\n                              - message: filter.cors must be nil if the filter.type\n                                  is not CORS\n                                rule: '!(has(self.cors) && self.type != ''CORS'')'\n                              - message: filter.cors must be specified for CORS filter.type\n                                rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                              - message: filter.requestHeaderModifier must be nil\n                                  if the filter.type is not RequestHeaderModifier\n                                rule: '!(has(self.requestHeaderModifier) && self.type\n                                  != ''RequestHeaderModifier'')'\n                              - message: filter.requestHeaderModifier must be specified\n                                  for RequestHeaderModifier filter.type\n                                rule: '!(!has(self.requestHeaderModifier) && self.type\n                                  == ''RequestHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be nil\n                                  if the filter.type is not ResponseHeaderModifier\n                                rule: '!(has(self.responseHeaderModifier) && self.type\n                                  != ''ResponseHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be specified\n                                  for ResponseHeaderModifier filter.type\n                                rule: '!(!has(self.responseHeaderModifier) && self.type\n                                  == ''ResponseHeaderModifier'')'\n                              - message: filter.requestMirror must be nil if the filter.type\n                                  is not RequestMirror\n                                rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                              - message: filter.requestMirror must be specified for\n                                  RequestMirror filter.type\n                                rule: '!(!has(self.requestMirror) && self.type ==\n                                  ''RequestMirror'')'\n                              - message: filter.requestRedirect must be nil if the\n                                  filter.type is not RequestRedirect\n                                rule: '!(has(self.requestRedirect) && self.type !=\n                                  ''RequestRedirect'')'\n                              - message: filter.requestRedirect must be specified\n                                  for RequestRedirect filter.type\n                                rule: '!(!has(self.requestRedirect) && self.type ==\n                                  ''RequestRedirect'')'\n                              - message: filter.urlRewrite must be nil if the filter.type\n                                  is not URLRewrite\n                                rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                              - message: filter.urlRewrite must be specified for URLRewrite\n                                  filter.type\n                                rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                              - message: filter.extensionRef must be nil if the filter.type\n                                  is not ExtensionRef\n                                rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                              - message: filter.extensionRef must be specified for\n                                  ExtensionRef filter.type\n                                rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                              - message: filter.externalAuth must be nil if the filter.type\n                                  is not ExternalAuth\n                                rule: '!(has(self.externalAuth) && self.type != ''ExternalAuth'')'\n                              - message: filter.externalAuth must be specified for\n                                  ExternalAuth filter.type\n                                rule: '!(!has(self.externalAuth) && self.type == ''ExternalAuth'')'\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-type: atomic\n                            x-kubernetes-validations:\n                            - message: May specify either httpRouteFilterRequestRedirect\n                                or httpRouteFilterRequestRewrite, but not both\n                              rule: '!(self.exists(f, f.type == ''RequestRedirect'')\n                                && self.exists(f, f.type == ''URLRewrite''))'\n                            - message: RequestHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                                <= 1\n                            - message: ResponseHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                                <= 1\n                            - message: RequestRedirect filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestRedirect').size()\n                                <= 1\n                            - message: URLRewrite filter cannot be repeated\n                              rule: self.filter(f, f.type == 'URLRewrite').size()\n                                <= 1\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    filters:\n                      description: |-\n                        Filters define the filters that are applied to requests that match\n                        this rule.\n\n                        Wherever possible, implementations SHOULD implement filters in the order\n                        they are specified.\n\n                        Implementations MAY choose to implement this ordering strictly, rejecting\n                        any combination or order of filters that cannot be supported. If implementations\n                        choose a strict interpretation of filter ordering, they MUST clearly document\n                        that behavior.\n\n                        To reject an invalid combination or order of filters, implementations SHOULD\n                        consider the Route Rules with this configuration invalid. If all Route Rules\n                        in a Route are invalid, the entire Route would be considered invalid. If only\n                        a portion of Route Rules are invalid, implementations MUST set the\n                        \"PartiallyInvalid\" condition for the Route.\n\n                        Conformance-levels at this level are defined based on the type of filter:\n\n                        - ALL core filters MUST be supported by all implementations.\n                        - Implementers are encouraged to support extended filters.\n                        - Implementation-specific custom filters have no API guarantees across\n                          implementations.\n\n                        Specifying the same filter multiple times is not supported unless explicitly\n                        indicated in the filter.\n\n                        All filters are expected to be compatible with each other except for the\n                        URLRewrite and RequestRedirect filters, which may not be combined. If an\n                        implementation cannot support other combinations of filters, they must clearly\n                        document that limitation. In cases where incompatible or unsupported\n                        filters are specified and cause the `Accepted` condition to be set to status\n                        `False`, implementations may use the `IncompatibleFilters` reason to specify\n                        this configuration error.\n\n                        Support: Core\n                      items:\n                        description: |-\n                          HTTPRouteFilter defines processing steps that must be completed during the\n                          request or response lifecycle. HTTPRouteFilters are meant as an extension\n                          point to express processing that may be done in Gateway implementations. Some\n                          examples include request or response modification, implementing\n                          authentication strategies, rate-limiting, and traffic shaping. API\n                          guarantee/conformance is defined based on the type of the filter.\n                        properties:\n                          cors:\n                            description: |-\n                              CORS defines a schema for a filter that responds to the\n                              cross-origin request based on HTTP response header.\n\n                              Support: Extended\n                            properties:\n                              allowCredentials:\n                                description: |-\n                                  AllowCredentials indicates whether the actual cross-origin request allows\n                                  to include credentials.\n\n                                  When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                  response header with value true (case-sensitive).\n\n                                  When set to false or omitted the gateway will omit the header\n                                  `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                  behavior).\n\n                                  Support: Extended\n                                type: boolean\n                              allowHeaders:\n                                description: |-\n                                  AllowHeaders indicates which HTTP request headers are supported for\n                                  accessing the requested resource.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  When the `AllowHeaders` field is configured with one or more headers, the\n                                  gateway must return the `Access-Control-Allow-Headers` response header\n                                  which value is present in the `AllowHeaders` field.\n\n                                  If any header name in the `Access-Control-Request-Headers` request header\n                                  is not included in the list of header names specified by the response\n                                  header `Access-Control-Allow-Headers`, it will present an error on the\n                                  client side.\n\n                                  If any header name in the `Access-Control-Allow-Headers` response header\n                                  does not recognize by the client, it will also occur an error on the\n                                  client side.\n\n                                  A wildcard indicates that the requests with all HTTP headers are allowed.\n                                  If config contains the wildcard \"*\" in allowHeaders and the request is\n                                  not credentialed, the `Access-Control-Allow-Headers` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Headers from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Headers` response header. When\n                                  also the `AllowCredentials` field is true and `AllowHeaders` field\n                                  is specified with the `*` wildcard, the gateway must specify one or more\n                                  HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                  header. The value of the header `Access-Control-Allow-Headers` is same as\n                                  the `Access-Control-Request-Headers` header provided by the client. If\n                                  the header `Access-Control-Request-Headers` is not included in the\n                                  request, the gateway will omit the `Access-Control-Allow-Headers`\n                                  response header, instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowHeaders cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowMethods:\n                                description: |-\n                                  AllowMethods indicates which HTTP methods are supported for accessing the\n                                  requested resource.\n\n                                  Valid values are any method defined by RFC9110, along with the special\n                                  value `*`, which represents all HTTP methods are allowed.\n\n                                  Method names are case-sensitive, so these values are also case-sensitive.\n                                  (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                  Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                  response header are separated by a comma (\",\").\n\n                                  A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                  CORS-safelisted methods are always allowed, regardless of whether they\n                                  are specified in the `AllowMethods` field.\n\n                                  When the `AllowMethods` field is configured with one or more methods, the\n                                  gateway must return the `Access-Control-Allow-Methods` response header\n                                  which value is present in the `AllowMethods` field.\n\n                                  If the HTTP method of the `Access-Control-Request-Method` request header\n                                  is not included in the list of methods specified by the response header\n                                  `Access-Control-Allow-Methods`, it will present an error on the client\n                                  side.\n\n                                  If config contains the wildcard \"*\" in allowMethods and the request is\n                                  not credentialed, the `Access-Control-Allow-Methods` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Method from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Methods` response header. When\n                                  also the `AllowCredentials` field is true and `AllowMethods` field\n                                  specified with the `*` wildcard, the gateway must specify one HTTP method\n                                  in the value of the Access-Control-Allow-Methods response header. The\n                                  value of the header `Access-Control-Allow-Methods` is same as the\n                                  `Access-Control-Request-Method` header provided by the client. If the\n                                  header `Access-Control-Request-Method` is not included in the request,\n                                  the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                  instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  enum:\n                                  - GET\n                                  - HEAD\n                                  - POST\n                                  - PUT\n                                  - DELETE\n                                  - CONNECT\n                                  - OPTIONS\n                                  - TRACE\n                                  - PATCH\n                                  - '*'\n                                  type: string\n                                maxItems: 9\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowMethods cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowOrigins:\n                                description: |-\n                                  AllowOrigins indicates whether the response can be shared with requested\n                                  resource from the given `Origin`.\n\n                                  The `Origin` consists of a scheme and a host, with an optional port, and\n                                  takes the form `<scheme>://<host>(:<port>)`.\n\n                                  Valid values for scheme are: `http` and `https`.\n\n                                  Valid values for port are any integer between 1 and 65535 (the list of\n                                  available TCP/UDP ports). Note that, if not included, port `80` is\n                                  assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                  origins. This may affect origin matching.\n\n                                  The host part of the origin may contain the wildcard character `*`. These\n                                  wildcard characters behave as follows:\n\n                                  * `*` is a greedy match to the _left_, including any number of\n                                    DNS labels to the left of its position. This also means that\n                                    `*` will include any number of period `.` characters to the\n                                    left of its position.\n                                  * A wildcard by itself matches all hosts.\n\n                                  An origin value that includes _only_ the `*` character indicates requests\n                                  from all `Origin`s are allowed.\n\n                                  When the `AllowOrigins` field is configured with multiple origins, it\n                                  means the server supports clients from multiple origins. If the request\n                                  `Origin` matches the configured allowed origins, the gateway must return\n                                  the given `Origin` and sets value of the header\n                                  `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                  client.\n\n                                  The status code of a successful response to a \"preflight\" request is\n                                  always an OK status (i.e., 204 or 200).\n\n                                  If the request `Origin` does not match the configured allowed origins,\n                                  the gateway returns 204/200 response but doesn't set the relevant\n                                  cross-origin response headers. Alternatively, the gateway responds with\n                                  403 status to the \"preflight\" request is denied, coupled with omitting\n                                  the CORS headers. The cross-origin request fails on the client side.\n                                  Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                  Conversely, if the request `Origin` matches one of the configured\n                                  allowed origins, the gateway sets the response header\n                                  `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                  header provided by the client.\n\n                                  When config has the wildcard (\"*\") in allowOrigins, and the request\n                                  is not credentialed (e.g., it is a preflight request), the\n                                  `Access-Control-Allow-Origin` response header either contains the\n                                  wildcard as well or the Origin from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Origin` response header. When\n                                  also the `AllowCredentials` field is true and `AllowOrigins` field\n                                  specified with the `*` wildcard, the gateway must return a single origin\n                                  in the value of the `Access-Control-Allow-Origin` response header,\n                                  instead of specifying the `*` wildcard. The value of the header\n                                  `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                  the client.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                    encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                    scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                    URIs that include an authority MUST include a fully qualified domain name or\n                                    IP address as the host.\n                                  maxLength: 253\n                                  minLength: 1\n                                  pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowOrigins cannot contain '*' alongside\n                                    other origins\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              exposeHeaders:\n                                description: |-\n                                  ExposeHeaders indicates which HTTP response headers can be exposed\n                                  to client-side scripts in response to a cross-origin request.\n\n                                  A CORS-safelisted response header is an HTTP header in a CORS response\n                                  that it is considered safe to expose to the client scripts.\n                                  The CORS-safelisted response headers include the following headers:\n                                  `Cache-Control`\n                                  `Content-Language`\n                                  `Content-Length`\n                                  `Content-Type`\n                                  `Expires`\n                                  `Last-Modified`\n                                  `Pragma`\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                  The CORS-safelisted response headers are exposed to client by default.\n\n                                  When an HTTP header name is specified using the `ExposeHeaders` field,\n                                  this additional header will be exposed as part of the response to the\n                                  client.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  A wildcard indicates that the responses with all HTTP headers are exposed\n                                  to clients. The `Access-Control-Expose-Headers` response header can only\n                                  use `*` wildcard as value when the request is not credentialed.\n\n                                  When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                  the request is credentialed, the gateway cannot use the `*` wildcard in\n                                  the `Access-Control-Expose-Headers` response header.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                              maxAge:\n                                default: 5\n                                description: |-\n                                  MaxAge indicates the duration (in seconds) for the client to cache the\n                                  results of a \"preflight\" request.\n\n                                  The information provided by the `Access-Control-Allow-Methods` and\n                                  `Access-Control-Allow-Headers` response headers can be cached by the\n                                  client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                  The default value of `Access-Control-Max-Age` response header is 5\n                                  (seconds).\n\n                                  When the `MaxAge` field is unspecified, the gateway sets the response\n                                  header \"Access-Control-Max-Age: 5\" by default.\n                                format: int32\n                                minimum: 1\n                                type: integer\n                            type: object\n                          extensionRef:\n                            description: |-\n                              ExtensionRef is an optional, implementation-specific extension to the\n                              \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                              \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                              extended filters.\n\n                              This filter can be used multiple times within the same rule.\n\n                              Support: Implementation-specific\n                            properties:\n                              group:\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is kind of the referent. For example\n                                  \"HTTPRoute\" or \"Service\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                            required:\n                            - group\n                            - kind\n                            - name\n                            type: object\n                          externalAuth:\n                            description: |-\n                              ExternalAuth configures settings related to sending request details\n                              to an external auth service. The external service MUST authenticate\n                              the request, and MAY authorize the request as well.\n\n                              If there is any problem communicating with the external service,\n                              this filter MUST fail closed.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef is a reference to a backend to send authorization\n                                  requests to.\n\n                                  The backend must speak the selected protocol (GRPC or HTTP) on the\n                                  referenced port.\n\n                                  If the backend service requires TLS, use BackendTLSPolicy to tell the\n                                  implementation to supply the TLS details to be used to connect to that\n                                  backend.\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              forwardBody:\n                                description: |-\n                                  ForwardBody controls if requests to the authorization server should include\n                                  the body of the client request; and if so, how big that body is allowed\n                                  to be.\n\n                                  It is expected that implementations will buffer the request body up to\n                                  `forwardBody.maxSize` bytes. Bodies over that size must be rejected with a\n                                  4xx series error (413 or 403 are common examples), and fail processing\n                                  of the filter.\n\n                                  If unset, or `forwardBody.maxSize` is set to `0`, then the body will not\n                                  be forwarded.\n\n                                  Feature Name: HTTPRouteExternalAuthForwardBody\n                                properties:\n                                  maxSize:\n                                    description: |-\n                                      MaxSize specifies how large in bytes the largest body that will be buffered\n                                      and sent to the authorization server. If the body size is larger than\n                                      `maxSize`, then the body sent to the authorization server must be\n                                      truncated to `maxSize` bytes.\n\n                                      Experimental note: This behavior needs to be checked against\n                                      various dataplanes; it may need to be changed.\n                                      See https://github.com/kubernetes-sigs/gateway-api/pull/4001#discussion_r2291405746\n                                      for more.\n\n                                      If 0, the body will not be sent to the authorization server.\n                                    type: integer\n                                type: object\n                              grpc:\n                                description: |-\n                                  GRPCAuthConfig contains configuration for communication with ext_authz\n                                  protocol-speaking backends.\n\n                                  If unset, implementations must assume the default behavior for each\n                                  included field is intended.\n                                properties:\n                                  allowedHeaders:\n                                    description: |-\n                                      AllowedRequestHeaders specifies what headers from the client request\n                                      will be sent to the authorization server.\n\n                                      If this list is empty, then all headers must be sent.\n\n                                      If the list has entries, only those entries must be sent.\n                                    items:\n                                      type: string\n                                    maxItems: 64\n                                    type: array\n                                    x-kubernetes-list-type: set\n                                type: object\n                              http:\n                                description: |-\n                                  HTTPAuthConfig contains configuration for communication with HTTP-speaking\n                                  backends.\n\n                                  If unset, implementations must assume the default behavior for each\n                                  included field is intended.\n                                properties:\n                                  allowedHeaders:\n                                    description: |-\n                                      AllowedRequestHeaders specifies what additional headers from the client request\n                                      will be sent to the authorization server.\n\n                                      The following headers must always be sent to the authorization server,\n                                      regardless of this setting:\n\n                                      * `Host`\n                                      * `Method`\n                                      * `Path`\n                                      * `Content-Length`\n                                      * `Authorization`\n\n                                      If this list is empty, then only those headers must be sent.\n\n                                      Note that `Content-Length` has a special behavior, in that the length\n                                      sent must be correct for the actual request to the external authorization\n                                      server - that is, it must reflect the actual number of bytes sent in the\n                                      body of the request to the authorization server.\n\n                                      So if the `forwardBody` stanza is unset, or `forwardBody.maxSize` is set\n                                      to `0`, then `Content-Length` must be `0`. If `forwardBody.maxSize` is set\n                                      to anything other than `0`, then the `Content-Length` of the authorization\n                                      request must be set to the actual number of bytes forwarded.\n                                    items:\n                                      type: string\n                                    maxItems: 64\n                                    type: array\n                                    x-kubernetes-list-type: set\n                                  allowedResponseHeaders:\n                                    description: |-\n                                      AllowedResponseHeaders specifies what headers from the authorization response\n                                      will be copied into the request to the backend.\n\n                                      If this list is empty, then all headers from the authorization server\n                                      except Authority or Host must be copied.\n                                    items:\n                                      type: string\n                                    maxItems: 64\n                                    type: array\n                                    x-kubernetes-list-type: set\n                                  path:\n                                    description: |-\n                                      Path sets the prefix that paths from the client request will have added\n                                      when forwarded to the authorization server.\n\n                                      When empty or unspecified, no prefix is added.\n\n                                      Valid values are the same as the \"value\" regex for path values in the `match`\n                                      stanza, and the validation regex will screen out invalid paths in the same way.\n                                      Even with the validation, implementations MUST sanitize this input before using it\n                                      directly.\n                                    maxLength: 1024\n                                    pattern: ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$\n                                    type: string\n                                type: object\n                              protocol:\n                                description: |-\n                                  ExternalAuthProtocol describes which protocol to use when communicating with an\n                                  ext_authz authorization server.\n\n                                  When this is set to GRPC, each backend must use the Envoy ext_authz protocol\n                                  on the port specified in `backendRefs`. Requests and responses are defined\n                                  in the protobufs explained at:\n                                  https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto\n\n                                  When this is set to HTTP, each backend must respond with a `200` status\n                                  code in on a successful authorization. Any other code is considered\n                                  an authorization failure.\n\n                                  Feature Names:\n                                  GRPC Support - HTTPRouteExternalAuthGRPC\n                                  HTTP Support - HTTPRouteExternalAuthHTTP\n                                enum:\n                                - HTTP\n                                - GRPC\n                                type: string\n                            required:\n                            - backendRef\n                            - protocol\n                            type: object\n                            x-kubernetes-validations:\n                            - message: grpc must be specified when protocol is set\n                                to 'GRPC'\n                              rule: 'self.protocol == ''GRPC'' ? has(self.grpc) :\n                                true'\n                            - message: protocol must be 'GRPC' when grpc is set\n                              rule: 'has(self.grpc) ? self.protocol == ''GRPC'' :\n                                true'\n                            - message: http must be specified when protocol is set\n                                to 'HTTP'\n                              rule: 'self.protocol == ''HTTP'' ? has(self.http) :\n                                true'\n                            - message: protocol must be 'HTTP' when http is set\n                              rule: 'has(self.http) ? self.protocol == ''HTTP'' :\n                                true'\n                          requestHeaderModifier:\n                            description: |-\n                              RequestHeaderModifier defines a schema for a filter that modifies request\n                              headers.\n\n                              Support: Core\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          requestMirror:\n                            description: |-\n                              RequestMirror defines a schema for a filter that mirrors requests.\n                              Requests are sent to the specified destination, but responses from\n                              that destination are ignored.\n\n                              This filter can be used multiple times within the same rule. Note that\n                              not all implementations will be able to support mirroring to multiple\n                              backends.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef references a resource where mirrored requests are sent.\n\n                                  Mirrored requests must be sent only to a single destination endpoint\n                                  within this BackendRef, irrespective of how many endpoints are present\n                                  within this BackendRef.\n\n                                  If the referent cannot be found, this BackendRef is invalid and must be\n                                  dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                  condition on the Route status is set to `status: False` and not configure\n                                  this backend in the underlying implementation.\n\n                                  If there is a cross-namespace reference to an *existing* object\n                                  that is not allowed by a ReferenceGrant, the controller must ensure the\n                                  \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                  with the \"RefNotPermitted\" reason and not configure this backend in the\n                                  underlying implementation.\n\n                                  In either error case, the Message of the `ResolvedRefs` Condition\n                                  should be used to provide more detail about the problem.\n\n                                  Support: Extended for Kubernetes Service\n\n                                  Support: Implementation-specific for any other resource\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              fraction:\n                                description: |-\n                                  Fraction represents the fraction of requests that should be\n                                  mirrored to BackendRef.\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                properties:\n                                  denominator:\n                                    default: 100\n                                    format: int32\n                                    minimum: 1\n                                    type: integer\n                                  numerator:\n                                    format: int32\n                                    minimum: 0\n                                    type: integer\n                                required:\n                                - numerator\n                                type: object\n                                x-kubernetes-validations:\n                                - message: numerator must be less than or equal to\n                                    denominator\n                                  rule: self.numerator <= self.denominator\n                              percent:\n                                description: |-\n                                  Percent represents the percentage of requests that should be\n                                  mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                  requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                format: int32\n                                maximum: 100\n                                minimum: 0\n                                type: integer\n                            required:\n                            - backendRef\n                            type: object\n                            x-kubernetes-validations:\n                            - message: Only one of percent or fraction may be specified\n                                in HTTPRequestMirrorFilter\n                              rule: '!(has(self.percent) && has(self.fraction))'\n                          requestRedirect:\n                            description: |-\n                              RequestRedirect defines a schema for a filter that responds to the\n                              request with an HTTP redirection.\n\n                              Support: Core\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the hostname to be used in the value of the `Location`\n                                  header in the response.\n                                  When empty, the hostname in the `Host` header of the request is used.\n\n                                  Support: Core\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines parameters used to modify the path of the incoming request.\n                                  The modified path is then used to construct the `Location` header. When\n                                  empty, the request path is used as-is.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                              port:\n                                description: |-\n                                  Port is the port to be used in the value of the `Location`\n                                  header in the response.\n\n                                  If no port is specified, the redirect port MUST be derived using the\n                                  following rules:\n\n                                  * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                    port associated with the redirect scheme. Specifically \"http\" to port 80\n                                    and \"https\" to port 443. If the redirect scheme does not have a\n                                    well-known port, the listener port of the Gateway SHOULD be used.\n                                  * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                    Listener port.\n\n                                  Implementations SHOULD NOT add the port number in the 'Location'\n                                  header in the following cases:\n\n                                  * A Location header that will use HTTP (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 80.\n                                  * A Location header that will use HTTPS (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                  Support: Extended\n                                format: int32\n                                maximum: 65535\n                                minimum: 1\n                                type: integer\n                              scheme:\n                                description: |-\n                                  Scheme is the scheme to be used in the value of the `Location` header in\n                                  the response. When empty, the scheme of the request is used.\n\n                                  Scheme redirects can affect the port of the redirect, for more information,\n                                  refer to the documentation for the port field of this filter.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Extended\n                                enum:\n                                - http\n                                - https\n                                type: string\n                              statusCode:\n                                default: 302\n                                description: |-\n                                  StatusCode is the HTTP status code to be used in response.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Core\n                                enum:\n                                - 301\n                                - 302\n                                - 303\n                                - 307\n                                - 308\n                                type: integer\n                            type: object\n                          responseHeaderModifier:\n                            description: |-\n                              ResponseHeaderModifier defines a schema for a filter that modifies response\n                              headers.\n\n                              Support: Extended\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: |-\n                                        Value is the value of HTTP Header to be matched.\n\n                                        Must consist of printable US-ASCII characters, optionally separated\n                                        by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                      maxLength: 4096\n                                      minLength: 1\n                                      pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          type:\n                            description: |-\n                              Type identifies the type of filter to apply. As with other API fields,\n                              types are classified into three conformance levels:\n\n                              - Core: Filter types and their corresponding configuration defined by\n                                \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                implementations must support core filters.\n\n                              - Extended: Filter types and their corresponding configuration defined by\n                                \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                are encouraged to support extended filters.\n\n                              - Implementation-specific: Filters that are defined and supported by\n                                specific vendors.\n                                In the future, filters showing convergence in behavior across multiple\n                                implementations will be considered for inclusion in extended or core\n                                conformance levels. Filter-specific configuration for such filters\n                                is specified using the ExtensionRef field. `Type` should be set to\n                                \"ExtensionRef\" for custom filters.\n\n                              Implementers are encouraged to define custom implementation types to\n                              extend the core API with implementation-specific behavior.\n\n                              If a reference to a custom filter type cannot be resolved, the filter\n                              MUST NOT be skipped. Instead, requests that would have been processed by\n                              that filter MUST receive a HTTP error response.\n\n                              Note that values may be added to this enum, implementations\n                              must ensure that unknown values will not cause a crash.\n\n                              Unknown values here must result in the implementation setting the\n                              Accepted Condition for the Route to `status: False`, with a\n                              Reason of `UnsupportedValue`.\n                            enum:\n                            - RequestHeaderModifier\n                            - ResponseHeaderModifier\n                            - RequestMirror\n                            - RequestRedirect\n                            - URLRewrite\n                            - ExtensionRef\n                            - CORS\n                            - ExternalAuth\n                            type: string\n                          urlRewrite:\n                            description: |-\n                              URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                              Support: Extended\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the value to be used to replace the Host header value during\n                                  forwarding.\n\n                                  Support: Extended\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines a path rewrite.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                            type: object\n                        required:\n                        - type\n                        type: object\n                        x-kubernetes-validations:\n                        - message: filter.cors must be nil if the filter.type is not\n                            CORS\n                          rule: '!(has(self.cors) && self.type != ''CORS'')'\n                        - message: filter.cors must be specified for CORS filter.type\n                          rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                        - message: filter.requestHeaderModifier must be nil if the\n                            filter.type is not RequestHeaderModifier\n                          rule: '!(has(self.requestHeaderModifier) && self.type !=\n                            ''RequestHeaderModifier'')'\n                        - message: filter.requestHeaderModifier must be specified\n                            for RequestHeaderModifier filter.type\n                          rule: '!(!has(self.requestHeaderModifier) && self.type ==\n                            ''RequestHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be nil if the\n                            filter.type is not ResponseHeaderModifier\n                          rule: '!(has(self.responseHeaderModifier) && self.type !=\n                            ''ResponseHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be specified\n                            for ResponseHeaderModifier filter.type\n                          rule: '!(!has(self.responseHeaderModifier) && self.type\n                            == ''ResponseHeaderModifier'')'\n                        - message: filter.requestMirror must be nil if the filter.type\n                            is not RequestMirror\n                          rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                        - message: filter.requestMirror must be specified for RequestMirror\n                            filter.type\n                          rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'\n                        - message: filter.requestRedirect must be nil if the filter.type\n                            is not RequestRedirect\n                          rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')'\n                        - message: filter.requestRedirect must be specified for RequestRedirect\n                            filter.type\n                          rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')'\n                        - message: filter.urlRewrite must be nil if the filter.type\n                            is not URLRewrite\n                          rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                        - message: filter.urlRewrite must be specified for URLRewrite\n                            filter.type\n                          rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                        - message: filter.extensionRef must be nil if the filter.type\n                            is not ExtensionRef\n                          rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                        - message: filter.extensionRef must be specified for ExtensionRef\n                            filter.type\n                          rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                        - message: filter.externalAuth must be nil if the filter.type\n                            is not ExternalAuth\n                          rule: '!(has(self.externalAuth) && self.type != ''ExternalAuth'')'\n                        - message: filter.externalAuth must be specified for ExternalAuth\n                            filter.type\n                          rule: '!(!has(self.externalAuth) && self.type == ''ExternalAuth'')'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                      x-kubernetes-validations:\n                      - message: May specify either httpRouteFilterRequestRedirect\n                          or httpRouteFilterRequestRewrite, but not both\n                        rule: '!(self.exists(f, f.type == ''RequestRedirect'') &&\n                          self.exists(f, f.type == ''URLRewrite''))'\n                      - message: RequestHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                          <= 1\n                      - message: ResponseHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                          <= 1\n                      - message: RequestRedirect filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestRedirect').size() <=\n                          1\n                      - message: URLRewrite filter cannot be repeated\n                        rule: self.filter(f, f.type == 'URLRewrite').size() <= 1\n                    matches:\n                      default:\n                      - path:\n                          type: PathPrefix\n                          value: /\n                      description: |-\n                        Matches define conditions used for matching the rule against incoming\n                        HTTP requests. Each match is independent, i.e. this rule will be matched\n                        if **any** one of the matches is satisfied.\n\n                        For example, take the following matches configuration:\n\n                        ```\n                        matches:\n                        - path:\n                            value: \"/foo\"\n                          headers:\n                          - name: \"version\"\n                            value: \"v2\"\n                        - path:\n                            value: \"/v2/foo\"\n                        ```\n\n                        For a request to match against this rule, a request must satisfy\n                        EITHER of the two conditions:\n\n                        - path prefixed with `/foo` AND contains the header `version: v2`\n                        - path prefix of `/v2/foo`\n\n                        See the documentation for HTTPRouteMatch on how to specify multiple\n                        match conditions that should be ANDed together.\n\n                        If no matches are specified, the default is a prefix\n                        path match on \"/\", which has the effect of matching every\n                        HTTP request.\n\n                        Proxy or Load Balancer routing configuration generated from HTTPRoutes\n                        MUST prioritize matches based on the following criteria, continuing on\n                        ties. Across all rules specified on applicable Routes, precedence must be\n                        given to the match having:\n\n                        * \"Exact\" path match.\n                        * \"Prefix\" path match with largest number of characters.\n                        * Method match.\n                        * Largest number of header matches.\n                        * Largest number of query param matches.\n\n                        Note: The precedence of RegularExpression path matches are implementation-specific.\n\n                        If ties still exist across multiple Routes, matching precedence MUST be\n                        determined in order of the following criteria, continuing on ties:\n\n                        * The oldest Route based on creation timestamp.\n                        * The Route appearing first in alphabetical order by\n                          \"{namespace}/{name}\".\n\n                        If ties still exist within an HTTPRoute, matching precedence MUST be granted\n                        to the FIRST matching rule (in list order) with a match meeting the above\n                        criteria.\n\n                        When no rules matching a request have been successfully attached to the\n                        parent a request is coming from, a HTTP 404 status code MUST be returned.\n                      items:\n                        description: \"HTTPRouteMatch defines the predicate used to\n                          match requests to a given\\naction. Multiple match types\n                          are ANDed together, i.e. the match will\\nevaluate to true\n                          only if all conditions are satisfied.\\n\\nFor example, the\n                          match below will match a HTTP request only if its path\\nstarts\n                          with `/foo` AND it contains the `version: v1` header:\\n\\n```\\nmatch:\\n\\n\\tpath:\\n\\t\n                          \\ value: \\\"/foo\\\"\\n\\theaders:\\n\\t- name: \\\"version\\\"\\n\\t\n                          \\ value \\\"v1\\\"\\n\\n```\"\n                        properties:\n                          headers:\n                            description: |-\n                              Headers specifies HTTP request header matchers. Multiple match values are\n                              ANDed together, meaning, a request must match all the specified headers\n                              to select the route.\n                            items:\n                              description: |-\n                                HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request\n                                headers.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                    case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                    If multiple entries specify equivalent header names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent header name MUST be ignored. Due to the\n                                    case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                    equivalent.\n\n                                    When a header is repeated in an HTTP request, it is\n                                    implementation-specific behavior as to how this is represented.\n                                    Generally, proxies should follow the guidance from the RFC:\n                                    https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding\n                                    processing a repeated header, with special handling for \"Set-Cookie\".\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the header.\n\n                                    Support: Core (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression HeaderMatchType has implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other dialects\n                                    of regular expressions. Please read the implementation's documentation to\n                                    determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: |-\n                                    Value is the value of HTTP Header to be matched.\n\n                                    Must consist of printable US-ASCII characters, optionally separated\n                                    by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2\n                                  maxLength: 4096\n                                  minLength: 1\n                                  pattern: ^[!-~]+([\\t ]?[!-~]+)*$\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                          method:\n                            description: |-\n                              Method specifies HTTP method matcher.\n                              When specified, this route will be matched only if the request has the\n                              specified method.\n\n                              Support: Extended\n                            enum:\n                            - GET\n                            - HEAD\n                            - POST\n                            - PUT\n                            - DELETE\n                            - CONNECT\n                            - OPTIONS\n                            - TRACE\n                            - PATCH\n                            type: string\n                          path:\n                            default:\n                              type: PathPrefix\n                              value: /\n                            description: |-\n                              Path specifies a HTTP request path matcher. If this field is not\n                              specified, a default prefix match on the \"/\" path is provided.\n                            properties:\n                              type:\n                                default: PathPrefix\n                                description: |-\n                                  Type specifies how to match against the path Value.\n\n                                  Support: Core (Exact, PathPrefix)\n\n                                  Support: Implementation-specific (RegularExpression)\n                                enum:\n                                - Exact\n                                - PathPrefix\n                                - RegularExpression\n                                type: string\n                              value:\n                                default: /\n                                description: Value of the HTTP path to match against.\n                                maxLength: 1024\n                                type: string\n                            type: object\n                            x-kubernetes-validations:\n                            - message: value must be an absolute path and start with\n                                '/' when type one of ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'')\n                                : true'\n                            - message: must not contain '//' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'')\n                                : true'\n                            - message: must not contain '/./' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'')\n                                : true'\n                            - message: must not contain '/../' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'')\n                                : true'\n                            - message: must not contain '%2f' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'')\n                                : true'\n                            - message: must not contain '%2F' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'')\n                                : true'\n                            - message: must not contain '#' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'')\n                                : true'\n                            - message: must not end with '/..' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'')\n                                : true'\n                            - message: must not end with '/.' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'')\n                                : true'\n                            - message: type must be one of ['Exact', 'PathPrefix',\n                                'RegularExpression']\n                              rule: self.type in ['Exact','PathPrefix'] || self.type\n                                == 'RegularExpression'\n                            - message: must only contain valid characters (matching\n                                ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$)\n                                for types ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r\"\"\"^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$\"\"\")\n                                : true'\n                          queryParams:\n                            description: |-\n                              QueryParams specifies HTTP query parameter matchers. Multiple match\n                              values are ANDed together, meaning, a request must match all the\n                              specified query parameters to select the route.\n\n                              Support: Extended\n                            items:\n                              description: |-\n                                HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP\n                                query parameters.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP query param to be matched. This must be an\n                                    exact string match. (See\n                                    https://tools.ietf.org/html/rfc7230#section-2.7.3).\n\n                                    If multiple entries specify equivalent query param names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent query param name MUST be ignored.\n\n                                    If a query param is repeated in an HTTP request, the behavior is\n                                    purposely left undefined, since different data planes have different\n                                    capabilities. However, it is *recommended* that implementations should\n                                    match against the first value of the param if the data plane supports it,\n                                    as this behavior is expected in other load balancing contexts outside of\n                                    the Gateway API.\n\n                                    Users SHOULD NOT route traffic based on repeated query params to guard\n                                    themselves against potential differences in the implementations.\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the query parameter.\n\n                                    Support: Extended (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression QueryParamMatchType has Implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other\n                                    dialects of regular expressions. Please read the implementation's\n                                    documentation to determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of HTTP query param\n                                    to be matched.\n                                  maxLength: 1024\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                        type: object\n                      maxItems: 64\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    retry:\n                      description: |-\n                        Retry defines the configuration for when to retry an HTTP request.\n\n                        Support: Extended\n                      properties:\n                        attempts:\n                          description: |-\n                            Attempts specifies the maximum number of times an individual request\n                            from the gateway to a backend should be retried.\n\n                            If the maximum number of retries has been attempted without a successful\n                            response from the backend, the Gateway MUST return an error.\n\n                            When this field is unspecified, the number of times to attempt to retry\n                            a backend request is implementation-specific.\n\n                            Support: Extended\n                          type: integer\n                        backoff:\n                          description: |-\n                            Backoff specifies the minimum duration a Gateway should wait between\n                            retry attempts and is represented in Gateway API Duration formatting.\n\n                            For example, setting the `rules[].retry.backoff` field to the value\n                            `100ms` will cause a backend request to first be retried approximately\n                            100 milliseconds after timing out or receiving a response code configured\n                            to be retriable.\n\n                            An implementation MAY use an exponential or alternative backoff strategy\n                            for subsequent retry attempts, MAY cap the maximum backoff duration to\n                            some amount greater than the specified minimum, and MAY add arbitrary\n                            jitter to stagger requests, as long as unsuccessful backend requests are\n                            not retried before the configured minimum duration.\n\n                            If a Request timeout (`rules[].timeouts.request`) is configured on the\n                            route, the entire duration of the initial request and any retry attempts\n                            MUST not exceed the Request timeout duration. If any retry attempts are\n                            still in progress when the Request timeout duration has been reached,\n                            these SHOULD be canceled if possible and the Gateway MUST immediately\n                            return a timeout error.\n\n                            If a BackendRequest timeout (`rules[].timeouts.backendRequest`) is\n                            configured on the route, any retry attempts which reach the configured\n                            BackendRequest timeout duration without a response SHOULD be canceled if\n                            possible and the Gateway should wait for at least the specified backoff\n                            duration before attempting to retry the backend request again.\n\n                            If a BackendRequest timeout is _not_ configured on the route, retry\n                            attempts MAY time out after an implementation default duration, or MAY\n                            remain pending until a configured Request timeout or implementation\n                            default duration for total request time is reached.\n\n                            When this field is unspecified, the time to wait between retry attempts\n                            is implementation-specific.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        codes:\n                          description: |-\n                            Codes defines the HTTP response status codes for which a backend request\n                            should be retried.\n\n                            Support: Extended\n                          items:\n                            description: |-\n                              HTTPRouteRetryStatusCode defines an HTTP response status code for\n                              which a backend request should be retried.\n\n                              Implementations MUST support the following status codes as retriable:\n\n                              * 500\n                              * 502\n                              * 503\n                              * 504\n\n                              Implementations MAY support specifying additional discrete values in the\n                              500-599 range.\n\n                              Implementations MAY support specifying discrete values in the 400-499 range,\n                              which are often inadvisable to retry.\n                            maximum: 599\n                            minimum: 400\n                            type: integer\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    sessionPersistence:\n                      description: |-\n                        SessionPersistence defines and configures session persistence\n                        for the route rule.\n\n                        Support: Extended\n                      properties:\n                        absoluteTimeout:\n                          description: |-\n                            AbsoluteTimeout defines the absolute timeout of the persistent\n                            session. Once the AbsoluteTimeout duration has elapsed, the\n                            session becomes invalid.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        cookieConfig:\n                          description: |-\n                            CookieConfig provides configuration settings that are specific\n                            to cookie-based session persistence.\n\n                            Support: Core\n                          properties:\n                            lifetimeType:\n                              default: Session\n                              description: |-\n                                LifetimeType specifies whether the cookie has a permanent or\n                                session-based lifetime. A permanent cookie persists until its\n                                specified expiry time, defined by the Expires or Max-Age cookie\n                                attributes, while a session cookie is deleted when the current\n                                session ends.\n\n                                When set to \"Permanent\", AbsoluteTimeout indicates the\n                                cookie's lifetime via the Expires or Max-Age cookie attributes\n                                and is required.\n\n                                When set to \"Session\", AbsoluteTimeout indicates the\n                                absolute lifetime of the cookie tracked by the gateway and\n                                is optional.\n\n                                Defaults to \"Session\".\n\n                                Support: Core for \"Session\" type\n\n                                Support: Extended for \"Permanent\" type\n                              enum:\n                              - Permanent\n                              - Session\n                              type: string\n                          type: object\n                        idleTimeout:\n                          description: |-\n                            IdleTimeout defines the idle timeout of the persistent session.\n                            Once the session has been idle for more than the specified\n                            IdleTimeout duration, the session becomes invalid.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        sessionName:\n                          description: |-\n                            SessionName defines the name of the persistent session token\n                            which may be reflected in the cookie or the header. Users\n                            should avoid reusing session names to prevent unintended\n                            consequences, such as rejection or unpredictable behavior.\n\n                            Support: Implementation-specific\n                          maxLength: 128\n                          type: string\n                        type:\n                          default: Cookie\n                          description: |-\n                            Type defines the type of session persistence such as through\n                            the use of a header or cookie. Defaults to cookie based session\n                            persistence.\n\n                            Support: Core for \"Cookie\" type\n\n                            Support: Extended for \"Header\" type\n                          enum:\n                          - Cookie\n                          - Header\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: AbsoluteTimeout must be specified when cookie lifetimeType\n                          is Permanent\n                        rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)\n                          || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'\n                      - message: cookieConfig can only be set with type Cookie\n                        rule: '!has(self.cookieConfig) || self.type == ''Cookie'''\n                    timeouts:\n                      description: |-\n                        Timeouts defines the timeouts that can be configured for an HTTP request.\n\n                        Support: Extended\n                      properties:\n                        backendRequest:\n                          description: |-\n                            BackendRequest specifies a timeout for an individual request from the gateway\n                            to a backend. This covers the time from when the request first starts being\n                            sent from the gateway to when the full response has been received from the backend.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            An entire client HTTP transaction with a gateway, covered by the Request timeout,\n                            may result in more than one call from the gateway to the destination backend,\n                            for example, if automatic retries are supported.\n\n                            The value of BackendRequest must be a Gateway API Duration string as defined by\n                            GEP-2257.  When this field is unspecified, its behavior is implementation-specific;\n                            when specified, the value of BackendRequest must be no more than the value of the\n                            Request timeout (since the Request timeout encompasses the BackendRequest timeout).\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        request:\n                          description: |-\n                            Request specifies the maximum duration for a gateway to respond to an HTTP request.\n                            If the gateway has not been able to respond before this deadline is met, the gateway\n                            MUST return a timeout error.\n\n                            For example, setting the `rules.timeouts.request` field to the value `10s` in an\n                            `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds\n                            to complete.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            This timeout is intended to cover as close to the whole request-response transaction\n                            as possible although an implementation MAY choose to start the timeout after the entire\n                            request stream has been received instead of immediately after the transaction is\n                            initiated by the client.\n\n                            The value of Request is a Gateway API Duration string as defined by GEP-2257. When this\n                            field is unspecified, request timeout behavior is implementation-specific.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: backendRequest timeout cannot be longer than request\n                          timeout\n                        rule: '!(has(self.request) && has(self.backendRequest) &&\n                          duration(self.request) != duration(''0s'') && duration(self.backendRequest)\n                          > duration(self.request))'\n                  type: object\n                  x-kubernetes-validations:\n                  - message: RequestRedirect filter must not be used together with\n                      backendRefs\n                    rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ?\n                      (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))):\n                      true'\n                  - message: When using RequestRedirect filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      ? ((size(self.matches) != 1 || !has(self.matches[0].path) ||\n                      self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: When using URLRewrite filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                  - message: Within backendRefs, when using RequestRedirect filter\n                      with path.replacePrefixMatch, exactly one PathPrefix match must\n                      be specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      )) ? ((size(self.matches) != 1 || !has(self.matches[0].path)\n                      || self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: Within backendRefs, When using URLRewrite filter with\n                      path.replacePrefixMatch, exactly one PathPrefix match must be\n                      specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: While 16 rules and 64 matches per rule are allowed, the\n                    total number of matches across all rules in a route must be less\n                    than 128\n                  rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size()\n                    > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size()\n                    : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size()\n                    > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size()\n                    : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size()\n                    > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size()\n                    : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size()\n                    > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size()\n                    : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size()\n                    > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size()\n                    : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128'\n                - message: Rule name must be unique within the route\n                  rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)\n                    && l1.name == l2.name))\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            type: object\n          status:\n            description: Status defines the current state of HTTPRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_listenersets.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: listenersets.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: ListenerSet\n    listKind: ListenerSetList\n    plural: listenersets\n    shortNames:\n    - lset\n    singular: listenerset\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ListenerSet defines a set of additional listeners to attach to an existing Gateway.\n          This resource provides a mechanism to merge multiple listeners into a single Gateway.\n\n          The parent Gateway must explicitly allow ListenerSet attachment through its\n          AllowedListeners configuration. By default, Gateways do not allow ListenerSet\n          attachment.\n\n          Routes can attach to a ListenerSet by specifying it as a parentRef, and can\n          optionally target specific listeners using the sectionName field.\n\n          Policy Attachment:\n          - Policies that attach to a ListenerSet apply to all listeners defined in that resource\n          - Policies do not impact listeners in the parent Gateway\n          - Different ListenerSets attached to the same Gateway can have different policies\n          - If an implementation cannot apply a policy to specific listeners, it should reject the policy\n\n          ReferenceGrant Semantics:\n          - ReferenceGrants applied to a Gateway are not inherited by child ListenerSets\n          - ReferenceGrants applied to a ListenerSet do not grant permission to the parent Gateway's listeners\n          - A ListenerSet can reference secrets/backends in its own namespace without a ReferenceGrant\n\n          Gateway Integration:\n            - The parent Gateway's status will include \"AttachedListenerSets\"\n              which is the count of ListenerSets that have successfully attached to a Gateway\n              A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n            - The ListenerSet is selected by the Gateway's AllowedListeners field\n            - The ListenerSet has a valid ParentRef selecting the Gateway\n            - The ListenerSet's status has the condition \"Accepted: true\"\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ListenerSet.\n            properties:\n              listeners:\n                description: |-\n                  Listeners associated with this ListenerSet. Listeners define\n                  logical endpoints that are bound on this referenced parent Gateway's addresses.\n\n                  Listeners in a `Gateway` and their attached `ListenerSets` are concatenated\n                  as a list when programming the underlying infrastructure. Each listener\n                  name does not need to be unique across the Gateway and ListenerSets.\n                  See ListenerEntry.Name for more details.\n\n                  Implementations MUST treat the parent Gateway as having the merged\n                  list of all listeners from itself and attached ListenerSets using\n                  the following precedence:\n\n                  1. \"parent\" Gateway\n                  2. ListenerSet ordered by creation time (oldest first)\n                  3. ListenerSet ordered alphabetically by \"{namespace}/{name}\".\n\n                  An implementation MAY reject listeners by setting the ListenerEntryStatus\n                  `Accepted` condition to False with the Reason `TooManyListeners`\n\n                  If a listener has a conflict, this will be reported in the\n                  Status.ListenerEntryStatus setting the `Conflicted` condition to True.\n\n                  Implementations SHOULD be cautious about what information from the\n                  parent or siblings are reported to avoid accidentally leaking\n                  sensitive information that the child would not otherwise have access\n                  to. This can include contents of secrets etc.\n                items:\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP\n                          protocol layers as described above. If an implementation does not\n                          ensure that both the SNI and Host header match the Listener hostname,\n                          it MUST clearly document that.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        ListenerSet.\n\n                        Name is not required to be unique across a Gateway and ListenerSets.\n                        Routes can attach to a Listener by having a ListenerSet as a parentRef\n                        and setting the SectionName\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    protocol:\n                      description: Protocol specifies the network protocol this listener\n                        expects to receive.\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - port\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: tls mode must be set for protocol TLS\n                  rule: 'self.all(l, (l.protocol == ''TLS'' ? has(l.tls) && has(l.tls.mode)\n                    && l.tls.mode != '''' : true))'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, !has(l1.port) || self.exists_one(l2, has(l2.port)\n                    && l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname)\n                    && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname)\n                    && !has(l2.hostname))))'\n              parentRef:\n                description: ParentRef references the Gateway that the listeners are\n                  attached to.\n                properties:\n                  group:\n                    default: gateway.networking.k8s.io\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    default: Gateway\n                    description: Kind is kind of the referent. For example \"Gateway\".\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.  If not present,\n                      the namespace of the referent is assumed to be the same as\n                      the namespace of the referring object.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - name\n                type: object\n            required:\n            - listeners\n            - parentRef\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of ListenerSet.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the ListenerSet.\n\n                  Implementations MUST express ListenerSet conditions using the\n                  `ListenerSetConditionType` and `ListenerSetConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe ListenerSet state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners, even if the Accepted condition of an individual Listener is set\n                        to \"False\". The AttachedRoutes number represents the number of Routes with\n                        the Accepted condition set to \"True\" that have been attached to this Listener.\n                        Routes with any other value for the Accepted condition MUST NOT be included\n                        in this count.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds supported by an implementation for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_referencegrants.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: referencegrants.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: ReferenceGrant\n    listKind: ReferenceGrantList\n    plural: referencegrants\n    shortNames:\n    - refgrant\n    singular: referencegrant\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ReferenceGrant identifies kinds of resources in other namespaces that are\n          trusted to reference the specified kinds of resources in the same namespace\n          as the policy.\n\n          Each ReferenceGrant can be used to represent a unique trust relationship.\n          Additional Reference Grants can be used to add to the set of trusted\n          sources of inbound references for the namespace they are defined within.\n\n          All cross-namespace references in Gateway API (with the exception of cross-namespace\n          Gateway-route attachment) require a ReferenceGrant.\n\n          ReferenceGrant is a form of runtime verification allowing users to assert\n          which cross-namespace object references are permitted. Implementations that\n          support ReferenceGrant MUST NOT permit cross-namespace references which have\n          no grant, and MUST respond to the removal of a grant by revoking the access\n          that the grant allowed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ReferenceGrant.\n            properties:\n              from:\n                description: |-\n                  From describes the trusted namespaces and kinds that can reference the\n                  resources described in \"To\". Each entry in this list MUST be considered\n                  to be an additional place that references can be valid from, or to put\n                  this another way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: ReferenceGrantFrom describes trusted namespaces and\n                    kinds.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field.\n\n                        When used to permit a SecretObjectReference:\n\n                        * Gateway\n\n                        When used to permit a BackendObjectReference:\n\n                        * GRPCRoute\n                        * HTTPRoute\n                        * TCPRoute\n                        * TLSRoute\n                        * UDPRoute\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - namespace\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n              to:\n                description: |-\n                  To describes the resources that may be referenced by the resources\n                  described in \"From\". Each entry in this list MUST be considered to be an\n                  additional place that references can be valid to, or to put this another\n                  way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: |-\n                    ReferenceGrantTo describes what Kinds are allowed as targets of the\n                    references.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field:\n\n                        * Secret when used to permit a SecretObjectReference\n                        * Service when used to permit a BackendObjectReference\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent. When unspecified, this policy\n                        refers to all resources of the specified Group and Kind in the local\n                        namespace.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - from\n            - to\n            type: object\n        type: object\n    served: true\n    storage: false\n    subresources: {}\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ReferenceGrant identifies kinds of resources in other namespaces that are\n          trusted to reference the specified kinds of resources in the same namespace\n          as the policy.\n\n          Each ReferenceGrant can be used to represent a unique trust relationship.\n          Additional Reference Grants can be used to add to the set of trusted\n          sources of inbound references for the namespace they are defined within.\n\n          All cross-namespace references in Gateway API (with the exception of cross-namespace\n          Gateway-route attachment) require a ReferenceGrant.\n\n          ReferenceGrant is a form of runtime verification allowing users to assert\n          which cross-namespace object references are permitted. Implementations that\n          support ReferenceGrant MUST NOT permit cross-namespace references which have\n          no grant, and MUST respond to the removal of a grant by revoking the access\n          that the grant allowed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ReferenceGrant.\n            properties:\n              from:\n                description: |-\n                  From describes the trusted namespaces and kinds that can reference the\n                  resources described in \"To\". Each entry in this list MUST be considered\n                  to be an additional place that references can be valid from, or to put\n                  this another way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: ReferenceGrantFrom describes trusted namespaces and\n                    kinds.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field.\n\n                        When used to permit a SecretObjectReference:\n\n                        * Gateway\n\n                        When used to permit a BackendObjectReference:\n\n                        * GRPCRoute\n                        * HTTPRoute\n                        * TCPRoute\n                        * TLSRoute\n                        * UDPRoute\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - namespace\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n              to:\n                description: |-\n                  To describes the resources that may be referenced by the resources\n                  described in \"From\". Each entry in this list MUST be considered to be an\n                  additional place that references can be valid to, or to put this another\n                  way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: |-\n                    ReferenceGrantTo describes what Kinds are allowed as targets of the\n                    references.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field:\n\n                        * Secret when used to permit a SecretObjectReference\n                        * Service when used to permit a BackendObjectReference\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent. When unspecified, this policy\n                        refers to all resources of the specified Group and Kind in the local\n                        namespace.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - from\n            - to\n            type: object\n        type: object\n    served: true\n    storage: true\n    subresources: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_tcproutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: tcproutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: TCPRoute\n    listKind: TCPRouteList\n    plural: tcproutes\n    singular: tcproute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha2\n    schema:\n      openAPIV3Schema:\n        description: |-\n          TCPRoute provides a way to route TCP requests. When combined with a Gateway\n          listener, it can be used to forward connections on the port specified by the\n          listener to a set of backends specified by the TCPRoute.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TCPRoute.\n            properties:\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                description: Rules are a list of TCP matchers and actions.\n                items:\n                  description: TCPRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or a\n                        Service with no endpoints), the underlying implementation MUST actively\n                        reject connection attempts to this backend. Connection rejections must\n                        respect weight; if an invalid backend is requested to have 80% of\n                        connections, then 80% of connections must be rejected instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Rule name must be unique within the route\n                  rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)\n                    && l1.name == l2.name))\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            required:\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TCPRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_tlsroutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: tlsroutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: TLSRoute\n    listKind: TLSRouteList\n    plural: tlsroutes\n    singular: tlsroute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The TLSRoute resource is similar to TCPRoute, but can be configured\n          to match against TLS-specific metadata. This allows more flexibility\n          in matching streams for a given TLS listener.\n\n          If you need to forward traffic to a single target for a TLS listener, you\n          could choose to use a TCPRoute with a TLS listener.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TLSRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of SNI hostnames that should match against the\n                  SNI attribute of TLS ClientHello message in TLS handshake. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed in SNI hostnames per RFC 6066.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Hostnames cannot contain an IP\n                  rule: self.all(h, !isIP(h))\n                - message: Hostnames must be valid based on RFC-1123\n                  rule: 'self.all(h, !h.contains(''*'') ? h.matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$'')\n                    : true)'\n                - message: Wildcards on hostnames must be the first label, and the\n                    rest of hostname must be valid based on RFC-1123\n                  rule: 'self.all(h, h.contains(''*'') ? (h.startsWith(''*.'') &&\n                    h.substring(2).matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$''))\n                    : true)'\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                description: Rules are a list of actions.\n                items:\n                  description: TLSRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or\n                        a Service with no endpoints), the rule performs no forwarding; if no\n                        filters are specified that would result in a response being sent, the\n                        underlying implementation must actively reject request attempts to this\n                        backend, by rejecting the connection or returning a 500 status code.\n                        Request rejections must respect weight; if an invalid backend is\n                        requested to have 80% of requests, then 80% of requests must be rejected\n                        instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: Name is the name of the route rule. This name MUST\n                        be unique within a Route if it is set.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 1\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            required:\n            - hostnames\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TLSRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    deprecated: true\n    deprecationWarning: The v1alpha2 version of TLSRoute has been deprecated and will\n      be removed in a future release of the API. Please upgrade to v1.\n    name: v1alpha2\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The TLSRoute resource is similar to TCPRoute, but can be configured\n          to match against TLS-specific metadata. This allows more flexibility\n          in matching streams for a given TLS listener.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TLSRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of SNI names that should match against the\n                  SNI attribute of TLS ClientHello message in TLS handshake. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed in SNI names per RFC 6066.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and TLSRoute, there\n                  must be at least one intersecting hostname for the TLSRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches TLSRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches TLSRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `test.example.com` and `*.example.com` would both match. On the other\n                    hand, `example.com` and `test.example.net` would not match.\n\n                  If both the Listener and TLSRoute have specified hostnames, any\n                  TLSRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  TLSRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` must not be considered for a match.\n\n                  If both the Listener and TLSRoute have specified hostnames, and none\n                  match with the criteria above, then the TLSRoute is not accepted. The\n                  implementation must raise an 'Accepted' Condition with a status of\n                  `False` in the corresponding RouteParentStatus.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                description: Rules are a list of TLS matchers and actions.\n                items:\n                  description: TLSRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or\n                        a Service with no endpoints), the rule performs no forwarding; if no\n                        filters are specified that would result in a response being sent, the\n                        underlying implementation must actively reject request attempts to this\n                        backend, by rejecting the connection or returning a 500 status code.\n                        Request rejections must respect weight; if an invalid backend is\n                        requested to have 80% of requests, then 80% of requests must be rejected\n                        instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: Name is the name of the route rule. This name MUST\n                        be unique within a Route if it is set.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Rule name must be unique within the route\n                  rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)\n                    && l1.name == l2.name))\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            required:\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TLSRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    deprecated: true\n    deprecationWarning: The v1alpha3 version of TLSRoute has been deprecated and will\n      be removed in a future release of the API. Please upgrade to v1.\n    name: v1alpha3\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The TLSRoute resource is similar to TCPRoute, but can be configured\n          to match against TLS-specific metadata. This allows more flexibility\n          in matching streams for a given TLS listener.\n\n          If you need to forward traffic to a single target for a TLS listener, you\n          could choose to use a TCPRoute with a TLS listener.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TLSRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of SNI hostnames that should match against the\n                  SNI attribute of TLS ClientHello message in TLS handshake. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed in SNI hostnames per RFC 6066.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Hostnames cannot contain an IP\n                  rule: self.all(h, !isIP(h))\n                - message: Hostnames must be valid based on RFC-1123\n                  rule: 'self.all(h, !h.contains(''*'') ? h.matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$'')\n                    : true)'\n                - message: Wildcards on hostnames must be the first label, and the\n                    rest of hostname must be valid based on RFC-1123\n                  rule: 'self.all(h, h.contains(''*'') ? (h.startsWith(''*.'') &&\n                    h.substring(2).matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$''))\n                    : true)'\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                description: Rules are a list of actions.\n                items:\n                  description: TLSRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or\n                        a Service with no endpoints), the rule performs no forwarding; if no\n                        filters are specified that would result in a response being sent, the\n                        underlying implementation must actively reject request attempts to this\n                        backend, by rejecting the connection or returning a 500 status code.\n                        Request rejections must respect weight; if an invalid backend is\n                        requested to have 80% of requests, then 80% of requests must be rejected\n                        instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: Name is the name of the route rule. This name MUST\n                        be unique within a Route if it is set.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 1\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            required:\n            - hostnames\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TLSRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_udproutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: udproutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: UDPRoute\n    listKind: UDPRouteList\n    plural: udproutes\n    singular: udproute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha2\n    schema:\n      openAPIV3Schema:\n        description: |-\n          UDPRoute provides a way to route UDP traffic. When combined with a Gateway\n          listener, it can be used to forward traffic on the port specified by the\n          listener to a set of backends specified by the UDPRoute.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of UDPRoute.\n            properties:\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n\n\n                  ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                  routes, which apply default routing rules to inbound connections from\n                  any namespace to the Service.\n\n                  ParentRefs from a Route to a Service in a different namespace are\n                  \"consumer\" routes, and these routing rules are only applied to outbound\n                  connections originating from the same namespace as the Route, for which\n                  the intended destination of the connections are a Service targeted as a\n                  ParentRef of the Route.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n\n                        ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                        routes, which apply default routing rules to inbound connections from\n                        any namespace to the Service.\n\n                        ParentRefs from a Route to a Service in a different namespace are\n                        \"consumer\" routes, and these routing rules are only applied to outbound\n                        connections originating from the same namespace as the Route, for which\n                        the intended destination of the connections are a Service targeted as a\n                        ParentRef of the Route.\n\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n\n                        When the parent resource is a Service, this targets a specific port in the\n                        Service spec. When both Port (experimental) and SectionName are specified,\n                        the name and port of the selected port must match both specified values.\n\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName or port must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port)\n                    || p2.port == 0)): true))'\n                - message: sectionName or port must be unique when parentRefs includes\n                    2 or more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port)\n                    || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port\n                    == p2.port))))\n              rules:\n                description: Rules are a list of UDP matchers and actions.\n                items:\n                  description: UDPRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or a\n                        Service with no endpoints), the underlying implementation MUST actively\n                        reject connection attempts to this backend. Packet drops must\n                        respect weight; if an invalid backend is requested to have 80% of\n                        the packets, then 80% of packets must be dropped instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n\n                          When the BackendRef points to a Kubernetes Service, implementations SHOULD\n                          honor the appProtocol field if it is set for the target Service Port.\n\n                          Implementations supporting appProtocol SHOULD recognize the Kubernetes\n                          Standard Application Protocols defined in KEP-3726.\n\n                          If a Service appProtocol isn't specified, an implementation MAY infer the\n                          backend protocol through its own means. Implementations MAY infer the\n                          protocol from the Route type referring to the backend Service.\n\n                          If a Route is not able to send traffic to the backend using the specified\n                          protocol then the backend is considered invalid. Implementations MUST set the\n                          \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason.\n\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Rule name must be unique within the route\n                  rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)\n                    && l1.name == l2.name))\n              useDefaultGateways:\n                description: |-\n                  UseDefaultGateways indicates the default Gateway scope to use for this\n                  Route. If unset (the default) or set to None, the Route will not be\n                  attached to any default Gateway; if set, it will be attached to any\n                  default Gateway supporting the named scope, subject to the usual rules\n                  about which Routes a Gateway is allowed to claim.\n\n                  Think carefully before using this functionality! The set of default\n                  Gateways supporting the requested scope can change over time without\n                  any notice to the Route author, and in many situations it will not be\n                  appropriate to request a default Gateway for a given Route -- for\n                  example, a Route with specific security requirements should almost\n                  certainly not use a default Gateway.\n                enum:\n                - All\n                - None\n                type: string\n            required:\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of UDPRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.k8s.io_vap_safeupgrades.yaml",
    "content": "apiVersion: admissionregistration.k8s.io/v1\nkind: ValidatingAdmissionPolicy\nmetadata:\n  annotations:\n    gateway.networking.k8s.io/bundle-version: v1.5.0-dev\n    gateway.networking.k8s.io/channel: standard\n  name: \"safe-upgrades.gateway.networking.k8s.io\"\nspec:\n  failurePolicy: Fail\n  matchConstraints:\n    resourceRules:\n    - apiGroups:   [\"apiextensions.k8s.io\"]\n      apiVersions: [\"v1\"]\n      operations:  [\"CREATE\", \"UPDATE\"]\n      resources:   [\"*\"]\n  validations:\n    - expression: \"object.spec.group != 'gateway.networking.k8s.io' || (\n        has(object.metadata.annotations) && object.metadata.annotations.exists(k, k == 'gateway.networking.k8s.io/channel') && \n        object.metadata.annotations['gateway.networking.k8s.io/channel'] == 'standard' )\"\n      message: \"Installing experimental CRDs on top of standard channel CRDs is prohibited by default. Uninstall ValidatingAdmissionPolicy safe-upgrades.gateway.networking.k8s.io to install experimental CRDs on top of standard channel CRDs.\"\n      reason: Invalid\n    - expression: \"object.spec.group != 'gateway.networking.k8s.io' || \n        (has(object.metadata.annotations) && object.metadata.annotations.exists(k, k == 'gateway.networking.k8s.io/bundle-version') && \n        !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], 'v1.[0-3].\\\\\\\\d+') &&\n        !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], 'v0'))\" #TODO Kubernetes 1.37: Migrate to kubernetes semver library\n      message: \"Installing CRDs with version before v1.5.0 is prohibited by default. Uninstall ValidatingAdmissionPolicy safe-upgrades.gateway.networking.k8s.io to install older versions.\"\n      reason: Invalid\n\n---\n\napiVersion: admissionregistration.k8s.io/v1\nkind: ValidatingAdmissionPolicyBinding\nmetadata:\n  annotations:\n    gateway.networking.k8s.io/bundle-version: v1.5.0-dev\n    gateway.networking.k8s.io/channel: standard\n  name: safe-upgrades.gateway.networking.k8s.io\nspec:\n  policyName: safe-upgrades.gateway.networking.k8s.io\n  validationActions: [Deny]\n  matchResources:\n    resourceRules:\n    - apiGroups:   [\"apiextensions.k8s.io\"]\n      apiVersions: [\"v1\"]\n      resources:   [\"customresourcedefinitions\"]\n      operations:  [\"CREATE\", \"UPDATE\"]\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.x-k8s.io_xbackendtrafficpolicies.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  labels:\n    gateway.networking.k8s.io/policy: Direct\n  name: xbackendtrafficpolicies.gateway.networking.x-k8s.io\nspec:\n  group: gateway.networking.x-k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: XBackendTrafficPolicy\n    listKind: XBackendTrafficPolicyList\n    plural: xbackendtrafficpolicies\n    shortNames:\n    - xbtrafficpolicy\n    singular: xbackendtrafficpolicy\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          XBackendTrafficPolicy defines the configuration for how traffic to a\n          target backend should be handled.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of BackendTrafficPolicy.\n            properties:\n              retryConstraint:\n                description: |-\n                  RetryConstraint defines the configuration for when to allow or prevent\n                  further retries to a target backend, by dynamically calculating a 'retry\n                  budget'. This budget is calculated based on the percentage of incoming\n                  traffic composed of retries over a given time interval. Once the budget\n                  is exceeded, additional retries will be rejected.\n\n                  For example, if the retry budget interval is 10 seconds, there have been\n                  1000 active requests in the past 10 seconds, and the allowed percentage\n                  of requests that can be retried is 20% (the default), then 200 of those\n                  requests may be composed of retries. Active requests will only be\n                  considered for the duration of the interval when calculating the retry\n                  budget. Retrying the same original request multiple times within the\n                  retry budget interval will lead to each retry being counted towards\n                  calculating the budget.\n\n                  Configuring a RetryConstraint in BackendTrafficPolicy is compatible with\n                  HTTPRoute Retry settings for each HTTPRouteRule that targets the same\n                  backend. While the HTTPRouteRule Retry stanza can specify whether a\n                  request will be retried, and the number of retry attempts each client\n                  may perform, RetryConstraint helps prevent cascading failures such as\n                  retry storms during periods of consistent failures.\n\n                  After the retry budget has been exceeded, additional retries to the\n                  backend MUST return a 503 response to the client.\n\n                  Additional configurations for defining a constraint on retries MAY be\n                  defined in the future.\n\n                  Support: Extended\n                properties:\n                  budget:\n                    default:\n                      interval: 10s\n                      percent: 20\n                    description: Budget holds the details of the retry budget configuration.\n                    properties:\n                      interval:\n                        default: 10s\n                        description: |-\n                          Interval defines the duration in which requests will be considered\n                          for calculating the budget for retries.\n\n                          Support: Extended\n                        pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                        type: string\n                        x-kubernetes-validations:\n                        - message: interval cannot be greater than one hour or less\n                            than one second\n                          rule: '!(duration(self) < duration(''1s'') || duration(self)\n                            > duration(''1h''))'\n                      percent:\n                        default: 20\n                        description: |-\n                          Percent defines the maximum percentage of active requests that may\n                          be made up of retries.\n\n                          Support: Extended\n                        maximum: 100\n                        minimum: 0\n                        type: integer\n                    type: object\n                  minRetryRate:\n                    default:\n                      count: 10\n                      interval: 1s\n                    description: |-\n                      MinRetryRate defines the minimum rate of retries that will be allowable\n                      over a specified duration of time.\n\n                      The effective overall minimum rate of retries targeting the backend\n                      service may be much higher, as there can be any number of clients which\n                      are applying this setting locally.\n\n                      This ensures that requests can still be retried during periods of low\n                      traffic, where the budget for retries may be calculated as a very low\n                      value.\n\n                      Support: Extended\n                    properties:\n                      count:\n                        description: |-\n                          Count specifies the number of requests per time interval.\n\n                          Support: Extended\n                        maximum: 1000000\n                        minimum: 1\n                        type: integer\n                      interval:\n                        description: |-\n                          Interval specifies the divisor of the rate of requests, the amount of\n                          time during which the given count of requests occur.\n\n                          Support: Extended\n                        pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                        type: string\n                        x-kubernetes-validations:\n                        - message: interval cannot be greater than one hour\n                          rule: '!(duration(self) == duration(''0s'') || duration(self)\n                            > duration(''1h''))'\n                    type: object\n                type: object\n              sessionPersistence:\n                description: |-\n                  SessionPersistence defines and configures session persistence\n                  for the backend.\n\n                  Support: Extended\n                properties:\n                  absoluteTimeout:\n                    description: |-\n                      AbsoluteTimeout defines the absolute timeout of the persistent\n                      session. Once the AbsoluteTimeout duration has elapsed, the\n                      session becomes invalid.\n\n                      Support: Extended\n                    pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                    type: string\n                  cookieConfig:\n                    description: |-\n                      CookieConfig provides configuration settings that are specific\n                      to cookie-based session persistence.\n\n                      Support: Core\n                    properties:\n                      lifetimeType:\n                        default: Session\n                        description: |-\n                          LifetimeType specifies whether the cookie has a permanent or\n                          session-based lifetime. A permanent cookie persists until its\n                          specified expiry time, defined by the Expires or Max-Age cookie\n                          attributes, while a session cookie is deleted when the current\n                          session ends.\n\n                          When set to \"Permanent\", AbsoluteTimeout indicates the\n                          cookie's lifetime via the Expires or Max-Age cookie attributes\n                          and is required.\n\n                          When set to \"Session\", AbsoluteTimeout indicates the\n                          absolute lifetime of the cookie tracked by the gateway and\n                          is optional.\n\n                          Defaults to \"Session\".\n\n                          Support: Core for \"Session\" type\n\n                          Support: Extended for \"Permanent\" type\n                        enum:\n                        - Permanent\n                        - Session\n                        type: string\n                    type: object\n                  idleTimeout:\n                    description: |-\n                      IdleTimeout defines the idle timeout of the persistent session.\n                      Once the session has been idle for more than the specified\n                      IdleTimeout duration, the session becomes invalid.\n\n                      Support: Extended\n                    pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                    type: string\n                  sessionName:\n                    description: |-\n                      SessionName defines the name of the persistent session token\n                      which may be reflected in the cookie or the header. Users\n                      should avoid reusing session names to prevent unintended\n                      consequences, such as rejection or unpredictable behavior.\n\n                      Support: Implementation-specific\n                    maxLength: 128\n                    type: string\n                  type:\n                    default: Cookie\n                    description: |-\n                      Type defines the type of session persistence such as through\n                      the use of a header or cookie. Defaults to cookie based session\n                      persistence.\n\n                      Support: Core for \"Cookie\" type\n\n                      Support: Extended for \"Header\" type\n                    enum:\n                    - Cookie\n                    - Header\n                    type: string\n                type: object\n                x-kubernetes-validations:\n                - message: AbsoluteTimeout must be specified when cookie lifetimeType\n                    is Permanent\n                  rule: '!has(self.cookieConfig) || !has(self.cookieConfig.lifetimeType)\n                    || self.cookieConfig.lifetimeType != ''Permanent'' || has(self.absoluteTimeout)'\n                - message: cookieConfig can only be set with type Cookie\n                  rule: '!has(self.cookieConfig) || self.type == ''Cookie'''\n              targetRefs:\n                description: |-\n                  TargetRefs identifies API object(s) to apply this policy to.\n                  Currently, Backends (A grouping of like endpoints such as Service,\n                  ServiceImport, or any implementation-specific backendRef) are the only\n                  valid API target references.\n\n                  Currently, a TargetRef cannot be scoped to a specific port on a\n                  Service.\n                items:\n                  description: |-\n                    LocalPolicyTargetReference identifies an API object to apply a direct or\n                    inherited policy to. This should be used as part of Policy resources\n                    that can target Gateway API resources. For more information on how this\n                    policy attachment model works, and a sample Policy resource, refer to\n                    the policy attachment documentation for Gateway API.\n                  properties:\n                    group:\n                      description: Group is the group of the target resource.\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: Kind is kind of the target resource.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: Name is the name of the target resource.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - name\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - group\n                - kind\n                - name\n                x-kubernetes-list-type: map\n            required:\n            - targetRefs\n            type: object\n          status:\n            description: Status defines the current state of BackendTrafficPolicy.\n            properties:\n              ancestors:\n                description: |-\n                  Ancestors is a list of ancestor resources (usually Gateways) that are\n                  associated with the policy, and the status of the policy with respect to\n                  each ancestor. When this policy attaches to a parent, the controller that\n                  manages the parent and the ancestors MUST add an entry to this list when\n                  the controller first sees the policy and SHOULD update the entry as\n                  appropriate when the relevant ancestor is modified.\n\n                  Note that choosing the relevant ancestor is left to the Policy designers;\n                  an important part of Policy design is designing the right object level at\n                  which to namespace this status.\n\n                  Note also that implementations MUST ONLY populate ancestor status for\n                  the Ancestor resources they are responsible for. Implementations MUST\n                  use the ControllerName field to uniquely identify the entries in this list\n                  that they are responsible for.\n\n                  Note that to achieve this, the list of PolicyAncestorStatus structs\n                  MUST be treated as a map with a composite key, made up of the AncestorRef\n                  and ControllerName fields combined.\n\n                  A maximum of 16 ancestors will be represented in this list. An empty list\n                  means the Policy is not relevant for any ancestors.\n\n                  If this slice is full, implementations MUST NOT add further entries.\n                  Instead they MUST consider the policy unimplementable and signal that\n                  on any related resources such as the ancestor that would be referenced\n                  here. For example, if this list was full on BackendTLSPolicy, no\n                  additional Gateways would be able to reference the Service targeted by\n                  the BackendTLSPolicy.\n                items:\n                  description: |-\n                    PolicyAncestorStatus describes the status of a route with respect to an\n                    associated Ancestor.\n\n                    Ancestors refer to objects that are either the Target of a policy or above it\n                    in terms of object hierarchy. For example, if a policy targets a Service, the\n                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\n                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\n                    useful object to place Policy status on, so we recommend that implementations\n                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers\n                    have a _very_ good reason otherwise.\n\n                    In the context of policy attachment, the Ancestor is used to distinguish which\n                    resource results in a distinct application of this policy. For example, if a policy\n                    targets a Service, it may have a distinct result per attached Gateway.\n\n                    Policies targeting the same resource may have different effects depending on the\n                    ancestors of those resources. For example, different Gateways targeting the same\n                    Service may have different capabilities, especially if they have different underlying\n                    implementations.\n\n                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is\n                    used as a backend in a HTTPRoute that is itself attached to a Gateway.\n                    In this case, the relevant object for status is the Gateway, and that is the\n                    ancestor object referred to in this status.\n\n                    Note that a parent is also an ancestor, so for objects where the parent is the\n                    relevant object for status, this struct SHOULD still be used.\n\n                    This struct is intended to be used in a slice that's effectively a map,\n                    with a composite key made up of the AncestorRef and the ControllerName.\n                  properties:\n                    ancestorRef:\n                      description: |-\n                        AncestorRef corresponds with a ParentRef in the spec that this\n                        PolicyAncestorStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n\n                            ParentRefs from a Route to a Service in the same namespace are \"producer\"\n                            routes, which apply default routing rules to inbound connections from\n                            any namespace to the Service.\n\n                            ParentRefs from a Route to a Service in a different namespace are\n                            \"consumer\" routes, and these routing rules are only applied to outbound\n                            connections originating from the same namespace as the Route, for which\n                            the intended destination of the connections are a Service targeted as a\n                            ParentRef of the Route.\n\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n\n                            When the parent resource is a Service, this targets a specific port in the\n                            Service spec. When both Port (experimental) and SectionName are specified,\n                            the name and port of the selected port must match both specified values.\n\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    conditions:\n                      description: Conditions describes the status of the Policy with\n                        respect to the given Ancestor.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                  required:\n                  - ancestorRef\n                  - conditions\n                  - controllerName\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - ancestors\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.0\n    gateway.networking.k8s.io/channel: experimental\n  name: xlistenersets.gateway.networking.x-k8s.io\nspec:\n  group: gateway.networking.x-k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: XListenerSet\n    listKind: XListenerSetList\n    plural: xlistenersets\n    shortNames:\n    - lset\n    singular: xlistenerset\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          XListenerSet defines a set of additional listeners to attach to an existing Gateway.\n          This resource provides a mechanism to merge multiple listeners into a single Gateway.\n\n          The parent Gateway must explicitly allow ListenerSet attachment through its\n          AllowedListeners configuration. By default, Gateways do not allow ListenerSet\n          attachment.\n\n          Routes can attach to a ListenerSet by specifying it as a parentRef, and can\n          optionally target specific listeners using the sectionName field.\n\n          Policy Attachment:\n          - Policies that attach to a ListenerSet apply to all listeners defined in that resource\n          - Policies do not impact listeners in the parent Gateway\n          - Different ListenerSets attached to the same Gateway can have different policies\n          - If an implementation cannot apply a policy to specific listeners, it should reject the policy\n\n          ReferenceGrant Semantics:\n          - ReferenceGrants applied to a Gateway are not inherited by child ListenerSets\n          - ReferenceGrants applied to a ListenerSet do not grant permission to the parent Gateway's listeners\n          - A ListenerSet can reference secrets/backends in its own namespace without a ReferenceGrant\n\n          Gateway Integration:\n          - The parent Gateway's status will include an \"AttachedListenerSets\" condition\n          - This condition will be:\n            - True: when AllowedListeners is set and at least one child ListenerSet is attached\n            - False: when AllowedListeners is set but no valid listeners are attached, or when AllowedListeners is not set or false\n            - Unknown: when no AllowedListeners config is present\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ListenerSet.\n            properties:\n              listeners:\n                description: |-\n                  Listeners associated with this ListenerSet. Listeners define\n                  logical endpoints that are bound on this referenced parent Gateway's addresses.\n\n                  Listeners in a `Gateway` and their attached `ListenerSets` are concatenated\n                  as a list when programming the underlying infrastructure. Each listener\n                  name does not need to be unique across the Gateway and ListenerSets.\n                  See ListenerEntry.Name for more details.\n\n                  Implementations MUST treat the parent Gateway as having the merged\n                  list of all listeners from itself and attached ListenerSets using\n                  the following precedence:\n\n                  1. \"parent\" Gateway\n                  2. ListenerSet ordered by creation time (oldest first)\n                  3. ListenerSet ordered alphabetically by \"{namespace}/{name}\".\n\n                  An implementation MAY reject listeners by setting the ListenerEntryStatus\n                  `Accepted` condition to False with the Reason `TooManyListeners`\n\n                  If a listener has a conflict, this will be reported in the\n                  Status.ListenerEntryStatus setting the `Conflicted` condition to True.\n\n                  Implementations SHOULD be cautious about what information from the\n                  parent or siblings are reported to avoid accidentally leaking\n                  sensitive information that the child would not otherwise have access\n                  to. This can include contents of secrets etc.\n                items:\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP\n                          protocol layers as described above. If an implementation does not\n                          ensure that both the SNI and Host header match the Listener hostname,\n                          it MUST clearly document that.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        ListenerSet.\n\n                        Name is not required to be unique across a Gateway and ListenerSets.\n                        Routes can attach to a Listener by having a ListenerSet as a parentRef\n                        and setting the SectionName\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      default: 0\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n\n                        If the port is not set or specified as zero, the implementation will assign\n                        a unique port. If the implementation does not support dynamic port\n                        assignment, it MUST set `Accepted` condition to `False` with the\n                        `UnsupportedPort` reason.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    protocol:\n                      description: Protocol specifies the network protocol this listener\n                        expects to receive.\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, !has(l1.port) || self.exists_one(l2, has(l2.port)\n                    && l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname)\n                    && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname)\n                    && !has(l2.hostname))))'\n              parentRef:\n                description: ParentRef references the Gateway that the listeners are\n                  attached to.\n                properties:\n                  group:\n                    default: gateway.networking.k8s.io\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    default: Gateway\n                    description: Kind is kind of the referent. For example \"Gateway\".\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.  If not present,\n                      the namespace of the referent is assumed to be the same as\n                      the namespace of the referring object.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - name\n                type: object\n            required:\n            - listeners\n            - parentRef\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of ListenerSet.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the ListenerSet.\n\n                  Implementations MUST express ListenerSet conditions using the\n                  `ListenerSetConditionType` and `ListenerSetConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe ListenerSet state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener or Route status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners with condition Accepted: false and MUST count successfully\n                        attached Routes that may themselves have Accepted: false conditions.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: Port is the network port the listener is configured\n                        to listen on.\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds an implementation supports for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  - port\n                  - supportedKinds\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/gateway.networking.x-k8s.io_xmeshes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: experimental\n  name: xmeshes.gateway.networking.x-k8s.io\nspec:\n  group: gateway.networking.x-k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: XMesh\n    listKind: XMeshList\n    plural: xmeshes\n    shortNames:\n    - mesh\n    singular: xmesh\n  scope: Cluster\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: XMesh defines mesh-wide characteristics of a GAMMA-compliant\n          service mesh.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of XMesh.\n            properties:\n              controllerName:\n                description: |-\n                  ControllerName is the name of a controller that is managing Gateway API\n                  resources for mesh traffic management. The value of this field MUST be a\n                  domain prefixed path.\n\n                  Example: \"example.com/awesome-mesh\".\n\n                  This field is not mutable and cannot be empty.\n\n                  Support: Core\n                maxLength: 253\n                minLength: 1\n                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                type: string\n                x-kubernetes-validations:\n                - message: Value is immutable\n                  rule: self == oldSelf\n              description:\n                description: Description optionally provides a human-readable description\n                  of a Mesh.\n                maxLength: 64\n                type: string\n              parametersRef:\n                description: |-\n                  ParametersRef is an optional reference to a resource that contains\n                  implementation-specific configuration for this Mesh. If no\n                  implementation-specific parameters are needed, this field MUST be\n                  omitted.\n\n                  ParametersRef can reference a standard Kubernetes resource, i.e.\n                  ConfigMap, or an implementation-specific custom resource. The resource\n                  can be cluster-scoped or namespace-scoped.\n\n                  If the referent cannot be found, refers to an unsupported kind, or when\n                  the data within that resource is malformed, the Mesh MUST be rejected\n                  with the \"Accepted\" status condition set to \"False\" and an\n                  \"InvalidParameters\" reason.\n\n                  Support: Implementation-specific\n                properties:\n                  group:\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    description: Kind is kind of the referent.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.\n                      This field is required when referring to a Namespace-scoped resource and\n                      MUST be unset when referring to a Cluster-scoped resource.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - group\n                - kind\n                - name\n                type: object\n            required:\n            - controllerName\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n            description: Status defines the current state of XMesh.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions is the current status from the controller for\n                  this Mesh.\n\n                  Controllers should prefer to publish conditions using values\n                  of MeshConditionType for the type of each Condition.\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              supportedFeatures:\n                description: |-\n                  SupportedFeatures is the set of features the Mesh support.\n                  It MUST be sorted in ascending alphabetical order by the Name key.\n                items:\n                  properties:\n                    name:\n                      description: |-\n                        FeatureName is used to describe distinct features that are covered by\n                        conformance tests.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/experimental/kustomization.yaml",
    "content": "resources:\n- gateway.networking.k8s.io_backendtlspolicies.yaml\n- gateway.networking.k8s.io_gatewayclasses.yaml\n- gateway.networking.k8s.io_gateways.yaml\n- gateway.networking.k8s.io_grpcroutes.yaml\n- gateway.networking.k8s.io_httproutes.yaml\n- gateway.networking.k8s.io_listenersets.yaml\n- gateway.networking.k8s.io_referencegrants.yaml\n- gateway.networking.k8s.io_tcproutes.yaml\n- gateway.networking.k8s.io_tlsroutes.yaml\n- gateway.networking.k8s.io_udproutes.yaml\n- gateway.networking.k8s.io_vap_safeupgrades.yaml\n- gateway.networking.x-k8s.io_xbackendtrafficpolicies.yaml\n- gateway.networking.x-k8s.io_xmeshes.yaml\n"
  },
  {
    "path": "pkg/gateway/crds/kustomization.yaml",
    "content": "resources:\n- standard/gateway.networking.k8s.io_gatewayclasses.yaml\n- standard/gateway.networking.k8s.io_gateways.yaml\n- standard/gateway.networking.k8s.io_grpcroutes.yaml\n- standard/gateway.networking.k8s.io_httproutes.yaml\n- standard/gateway.networking.k8s.io_referencegrants.yaml\n- standard/gateway.networking.k8s.io_backendtlspolicies.yaml\n- standard/gateway.networking.k8s.io_listenersets.yaml\n- standard/gateway.networking.k8s.io_tlsroutes.yaml\n- standard/gateway.networking.k8s.io_vap_safeupgrades.yaml\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_backendtlspolicies.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  labels:\n    gateway.networking.k8s.io/policy: Direct\n  name: backendtlspolicies.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: BackendTLSPolicy\n    listKind: BackendTLSPolicyList\n    plural: backendtlspolicies\n    shortNames:\n    - btlspolicy\n    singular: backendtlspolicy\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          BackendTLSPolicy provides a way to configure how a Gateway\n          connects to a Backend via TLS.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of BackendTLSPolicy.\n            properties:\n              options:\n                additionalProperties:\n                  description: |-\n                    AnnotationValue is the value of an annotation in Gateway API. This is used\n                    for validation of maps such as TLS options. This roughly matches Kubernetes\n                    annotation validation, although the length validation in that case is based\n                    on the entire size of the annotations struct.\n                  maxLength: 4096\n                  minLength: 0\n                  type: string\n                description: |-\n                  Options are a list of key/value pairs to enable extended TLS\n                  configuration for each implementation. For example, configuring the\n                  minimum TLS version or supported cipher suites.\n\n                  A set of common keys MAY be defined by the API in the future. To avoid\n                  any ambiguity, implementation-specific definitions MUST use\n                  domain-prefixed names, such as `example.com/my-custom-option`.\n                  Un-prefixed names are reserved for key names defined by Gateway API.\n\n                  Support: Implementation-specific\n                maxProperties: 16\n                type: object\n              targetRefs:\n                description: |-\n                  TargetRefs identifies an API object to apply the policy to.\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n\n                  TargetRefs must be _distinct_. This means either that:\n\n                  * They select different targets. If this is the case, then targetRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, and `name` must\n                    be unique across all targetRef entries in the BackendTLSPolicy.\n                  * They select different sectionNames in the same target.\n\n                  When more than one BackendTLSPolicy selects the same target and\n                  sectionName, implementations MUST determine precedence using the\n                  following criteria, continuing on ties:\n\n                  * The older policy by creation timestamp takes precedence. For\n                    example, a policy with a creation timestamp of \"2021-07-15\n                    01:02:03\" MUST be given precedence over a policy with a\n                    creation timestamp of \"2021-07-15 01:02:04\".\n                  * The policy appearing first in alphabetical order by {namespace}/{name}.\n                    For example, a policy named `foo/bar` is given precedence over a\n                    policy named `foo/baz`.\n\n                  For any BackendTLSPolicy that does not take precedence, the\n                  implementation MUST ensure the `Accepted` Condition is set to\n                  `status: False`, with Reason `Conflicted`.\n\n                  Implementations SHOULD NOT support more than one targetRef at this\n                  time. Although the API technically allows for this, the current guidance\n                  for conflict resolution and status handling is lacking. Until that can be\n                  clarified in a future release, the safest approach is to support a single\n                  targetRef.\n\n                  Support Levels:\n\n                  * Extended: Kubernetes Service referenced by HTTPRoute backendRefs.\n\n                  * Implementation-Specific: Services not connected via HTTPRoute, and any\n                    other kind of backend. Implementations MAY use BackendTLSPolicy for:\n                    - Services not referenced by any Route (e.g., infrastructure services)\n                    - Gateway feature backends (e.g., ExternalAuth, rate-limiting services)\n                    - Service mesh workload-to-service communication\n                    - Other resource types beyond Service\n\n                  Implementations SHOULD aim to ensure that BackendTLSPolicy behavior is consistent,\n                  even outside of the extended HTTPRoute -(backendRef) -> Service path.\n                  They SHOULD clearly document how BackendTLSPolicy is interpreted in these\n                  scenarios, including:\n                    - Which resources beyond Service are supported\n                    - How the policy is discovered and applied\n                    - Any implementation-specific semantics or restrictions\n\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n                items:\n                  description: |-\n                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\n                    direct policy to. This should be used as part of Policy resources that can\n                    target single resources. For more information on how this policy attachment\n                    mode works, and a sample Policy resource, refer to the policy attachment\n                    documentation for Gateway API.\n\n                    Note: This should only be used for direct policy attachment when references\n                    to SectionName are actually needed. In all other cases,\n                    LocalPolicyTargetReference should be used.\n                  properties:\n                    group:\n                      description: Group is the group of the target resource.\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: Kind is kind of the target resource.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: Name is the name of the target resource.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. When\n                        unspecified, this targetRef targets the entire resource. In the following\n                        resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name\n                        * HTTPRoute: HTTPRouteRule name\n                        * Service: Port name\n\n                        If a SectionName is specified, but does not exist on the targeted object,\n                        the Policy must fail to attach, and the policy implementation should record\n                        a `ResolvedRefs` or similar Condition in the Policy's status.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - name\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when targetRefs includes\n                    2 or more references to the same target\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName\n                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))\n                    : true))'\n                - message: sectionName must be unique when targetRefs includes 2 or\n                    more references to the same target\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||\n                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              validation:\n                description: Validation contains backend TLS validation configuration.\n                properties:\n                  caCertificateRefs:\n                    description: |-\n                      CACertificateRefs contains one or more references to Kubernetes objects that\n                      contain a PEM-encoded TLS CA certificate bundle, which is used to\n                      validate a TLS handshake between the Gateway and backend Pod.\n\n                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be\n                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,\n                      not both. If CACertificateRefs is empty or unspecified, the configuration for\n                      WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\n                      A CACertificateRef is invalid if:\n\n                      * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key\n                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`\n                        and the Message of the Condition must indicate which reference is invalid and why.\n\n                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason\n                        must be set to `InvalidKind` and the Message of the Condition must explain which\n                        kind of resource is unknown or unsupported.\n\n                      * It refers to a resource in another namespace. This may change in future\n                        spec updates.\n\n                      Implementations MAY choose to perform further validation of the certificate\n                      content (e.g., checking expiry or enforcing specific formats). In such cases,\n                      an implementation-specific Reason and Message must be set for the invalid reference.\n\n                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on\n                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message\n                      that indicate the cause of the error. Connections using an invalid\n                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error\n                      response. If ALL CACertificateRefs are invalid, the implementation MUST also\n                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to\n                      `status: False`, with a Reason `NoValidCACertificate`.\n\n                      A single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support.\n                      Implementations MAY choose to support attaching multiple certificates to\n                      a backend, but this behavior is implementation-specific.\n\n                      Support: Core - An optional single reference to a Kubernetes ConfigMap,\n                      with the CA certificate in a key named `ca.crt`.\n\n                      Support: Implementation-specific - More than one reference, other kinds\n                      of resources, or a single reference that includes multiple certificates.\n                    items:\n                      description: |-\n                        LocalObjectReference identifies an API object within the namespace of the\n                        referrer.\n                        The API object must be valid in the cluster; the Group and Kind must\n                        be registered in the cluster for this reference to be valid.\n\n                        References to objects with invalid Group and Kind are not valid, and must\n                        be rejected by the implementation, with appropriate Conditions set\n                        on the containing object.\n                      properties:\n                        group:\n                          description: |-\n                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                            When unspecified or empty string, core API group is inferred.\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          description: Kind is kind of the referent. For example \"HTTPRoute\"\n                            or \"Service\".\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: Name is the name of the referent.\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                      required:\n                      - group\n                      - kind\n                      - name\n                      type: object\n                    maxItems: 8\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  hostname:\n                    description: |-\n                      Hostname is used for two purposes in the connection between Gateways and\n                      backends:\n\n                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).\n                      2. Hostname MUST be used for authentication and MUST match the certificate\n                         served by the matching backend, unless SubjectAltNames is specified.\n                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection\n                         but MUST NOT be used for authentication. If you want to use the value\n                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.\n\n                      Support: Core\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  subjectAltNames:\n                    description: |-\n                      SubjectAltNames contains one or more Subject Alternative Names.\n                      When specified the certificate served from the backend MUST\n                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\n                      Support: Extended\n                    items:\n                      description: SubjectAltName represents Subject Alternative Name.\n                      properties:\n                        hostname:\n                          description: |-\n                            Hostname contains Subject Alternative Name specified in DNS name format.\n                            Required when Type is set to Hostname, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        type:\n                          description: |-\n                            Type determines the format of the Subject Alternative Name. Always required.\n\n                            Support: Core\n                          enum:\n                          - Hostname\n                          - URI\n                          type: string\n                        uri:\n                          description: |-\n                            URI contains Subject Alternative Name specified in a full URI format.\n                            It MUST include both a scheme (e.g., \"http\" or \"ftp\") and a scheme-specific-part.\n                            Common values include SPIFFE IDs like \"spiffe://mycluster.example.com/ns/myns/sa/svc1sa\".\n                            Required when Type is set to URI, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\\?([^#]*))?(#(.*))?\n                          type: string\n                      required:\n                      - type\n                      type: object\n                      x-kubernetes-validations:\n                      - message: SubjectAltName element must contain Hostname, if\n                          Type is set to Hostname\n                        rule: '!(self.type == \"Hostname\" && (!has(self.hostname) ||\n                          self.hostname == \"\"))'\n                      - message: SubjectAltName element must not contain Hostname,\n                          if Type is not set to Hostname\n                        rule: '!(self.type != \"Hostname\" && has(self.hostname) &&\n                          self.hostname != \"\")'\n                      - message: SubjectAltName element must contain URI, if Type\n                          is set to URI\n                        rule: '!(self.type == \"URI\" && (!has(self.uri) || self.uri\n                          == \"\"))'\n                      - message: SubjectAltName element must not contain URI, if Type\n                          is not set to URI\n                        rule: '!(self.type != \"URI\" && has(self.uri) && self.uri !=\n                          \"\")'\n                    maxItems: 5\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  wellKnownCACertificates:\n                    description: |-\n                      WellKnownCACertificates specifies whether a well-known set of CA certificates\n                      may be used in the TLS handshake between the gateway and backend pod.\n\n                      If WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\n                      must be specified with at least one entry for a valid configuration. Only one of\n                      CACertificateRefs or WellKnownCACertificates may be specified, not both.\n                      If an implementation does not support the WellKnownCACertificates field, or\n                      the supplied value is not recognized, the implementation MUST ensure the\n                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\n                      a Reason `Invalid`.\n\n                      Valid values include:\n                      * \"System\" - indicates that well-known system CA certificates should be used.\n\n                      Implementations MAY define their own sets of CA certificates. Such definitions\n                      MUST use an implementation-specific, prefixed name, such as\n                      `mycompany.com/my-custom-ca-certifcates`.\n\n                      Support: Implementation-specific\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$\n                    type: string\n                required:\n                - hostname\n                type: object\n                x-kubernetes-validations:\n                - message: must not contain both CACertificateRefs and WellKnownCACertificates\n                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")'\n                - message: must specify either CACertificateRefs or WellKnownCACertificates\n                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")\n            required:\n            - targetRefs\n            - validation\n            type: object\n          status:\n            description: Status defines the current state of BackendTLSPolicy.\n            properties:\n              ancestors:\n                description: |-\n                  Ancestors is a list of ancestor resources (usually Gateways) that are\n                  associated with the policy, and the status of the policy with respect to\n                  each ancestor. When this policy attaches to a parent, the controller that\n                  manages the parent and the ancestors MUST add an entry to this list when\n                  the controller first sees the policy and SHOULD update the entry as\n                  appropriate when the relevant ancestor is modified.\n\n                  Note that choosing the relevant ancestor is left to the Policy designers;\n                  an important part of Policy design is designing the right object level at\n                  which to namespace this status.\n\n                  Note also that implementations MUST ONLY populate ancestor status for\n                  the Ancestor resources they are responsible for. Implementations MUST\n                  use the ControllerName field to uniquely identify the entries in this list\n                  that they are responsible for.\n\n                  Note that to achieve this, the list of PolicyAncestorStatus structs\n                  MUST be treated as a map with a composite key, made up of the AncestorRef\n                  and ControllerName fields combined.\n\n                  A maximum of 16 ancestors will be represented in this list. An empty list\n                  means the Policy is not relevant for any ancestors.\n\n                  If this slice is full, implementations MUST NOT add further entries.\n                  Instead they MUST consider the policy unimplementable and signal that\n                  on any related resources such as the ancestor that would be referenced\n                  here. For example, if this list was full on BackendTLSPolicy, no\n                  additional Gateways would be able to reference the Service targeted by\n                  the BackendTLSPolicy.\n                items:\n                  description: |-\n                    PolicyAncestorStatus describes the status of a route with respect to an\n                    associated Ancestor.\n\n                    Ancestors refer to objects that are either the Target of a policy or above it\n                    in terms of object hierarchy. For example, if a policy targets a Service, the\n                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\n                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\n                    useful object to place Policy status on, so we recommend that implementations\n                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers\n                    have a _very_ good reason otherwise.\n\n                    In the context of policy attachment, the Ancestor is used to distinguish which\n                    resource results in a distinct application of this policy. For example, if a policy\n                    targets a Service, it may have a distinct result per attached Gateway.\n\n                    Policies targeting the same resource may have different effects depending on the\n                    ancestors of those resources. For example, different Gateways targeting the same\n                    Service may have different capabilities, especially if they have different underlying\n                    implementations.\n\n                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is\n                    used as a backend in a HTTPRoute that is itself attached to a Gateway.\n                    In this case, the relevant object for status is the Gateway, and that is the\n                    ancestor object referred to in this status.\n\n                    Note that a parent is also an ancestor, so for objects where the parent is the\n                    relevant object for status, this struct SHOULD still be used.\n\n                    This struct is intended to be used in a slice that's effectively a map,\n                    with a composite key made up of the AncestorRef and the ControllerName.\n                  properties:\n                    ancestorRef:\n                      description: |-\n                        AncestorRef corresponds with a ParentRef in the spec that this\n                        PolicyAncestorStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    conditions:\n                      description: Conditions describes the status of the Policy with\n                        respect to the given Ancestor.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                  required:\n                  - ancestorRef\n                  - conditions\n                  - controllerName\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - ancestors\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - deprecated: true\n    deprecationWarning: The v1alpha3 version of BackendTLSPolicy has been deprecated\n      and will be removed in a future release of the API. Please upgrade to v1.\n    name: v1alpha3\n    schema:\n      openAPIV3Schema:\n        description: |-\n          BackendTLSPolicy provides a way to configure how a Gateway\n          connects to a Backend via TLS.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of BackendTLSPolicy.\n            properties:\n              options:\n                additionalProperties:\n                  description: |-\n                    AnnotationValue is the value of an annotation in Gateway API. This is used\n                    for validation of maps such as TLS options. This roughly matches Kubernetes\n                    annotation validation, although the length validation in that case is based\n                    on the entire size of the annotations struct.\n                  maxLength: 4096\n                  minLength: 0\n                  type: string\n                description: |-\n                  Options are a list of key/value pairs to enable extended TLS\n                  configuration for each implementation. For example, configuring the\n                  minimum TLS version or supported cipher suites.\n\n                  A set of common keys MAY be defined by the API in the future. To avoid\n                  any ambiguity, implementation-specific definitions MUST use\n                  domain-prefixed names, such as `example.com/my-custom-option`.\n                  Un-prefixed names are reserved for key names defined by Gateway API.\n\n                  Support: Implementation-specific\n                maxProperties: 16\n                type: object\n              targetRefs:\n                description: |-\n                  TargetRefs identifies an API object to apply the policy to.\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n\n                  TargetRefs must be _distinct_. This means either that:\n\n                  * They select different targets. If this is the case, then targetRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, and `name` must\n                    be unique across all targetRef entries in the BackendTLSPolicy.\n                  * They select different sectionNames in the same target.\n\n                  When more than one BackendTLSPolicy selects the same target and\n                  sectionName, implementations MUST determine precedence using the\n                  following criteria, continuing on ties:\n\n                  * The older policy by creation timestamp takes precedence. For\n                    example, a policy with a creation timestamp of \"2021-07-15\n                    01:02:03\" MUST be given precedence over a policy with a\n                    creation timestamp of \"2021-07-15 01:02:04\".\n                  * The policy appearing first in alphabetical order by {namespace}/{name}.\n                    For example, a policy named `foo/bar` is given precedence over a\n                    policy named `foo/baz`.\n\n                  For any BackendTLSPolicy that does not take precedence, the\n                  implementation MUST ensure the `Accepted` Condition is set to\n                  `status: False`, with Reason `Conflicted`.\n\n                  Implementations SHOULD NOT support more than one targetRef at this\n                  time. Although the API technically allows for this, the current guidance\n                  for conflict resolution and status handling is lacking. Until that can be\n                  clarified in a future release, the safest approach is to support a single\n                  targetRef.\n\n                  Support Levels:\n\n                  * Extended: Kubernetes Service referenced by HTTPRoute backendRefs.\n\n                  * Implementation-Specific: Services not connected via HTTPRoute, and any\n                    other kind of backend. Implementations MAY use BackendTLSPolicy for:\n                    - Services not referenced by any Route (e.g., infrastructure services)\n                    - Gateway feature backends (e.g., ExternalAuth, rate-limiting services)\n                    - Service mesh workload-to-service communication\n                    - Other resource types beyond Service\n\n                  Implementations SHOULD aim to ensure that BackendTLSPolicy behavior is consistent,\n                  even outside of the extended HTTPRoute -(backendRef) -> Service path.\n                  They SHOULD clearly document how BackendTLSPolicy is interpreted in these\n                  scenarios, including:\n                    - Which resources beyond Service are supported\n                    - How the policy is discovered and applied\n                    - Any implementation-specific semantics or restrictions\n\n                  Note that this config applies to the entire referenced resource\n                  by default, but this default may change in the future to provide\n                  a more granular application of the policy.\n                items:\n                  description: |-\n                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a\n                    direct policy to. This should be used as part of Policy resources that can\n                    target single resources. For more information on how this policy attachment\n                    mode works, and a sample Policy resource, refer to the policy attachment\n                    documentation for Gateway API.\n\n                    Note: This should only be used for direct policy attachment when references\n                    to SectionName are actually needed. In all other cases,\n                    LocalPolicyTargetReference should be used.\n                  properties:\n                    group:\n                      description: Group is the group of the target resource.\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: Kind is kind of the target resource.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: Name is the name of the target resource.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. When\n                        unspecified, this targetRef targets the entire resource. In the following\n                        resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name\n                        * HTTPRoute: HTTPRouteRule name\n                        * Service: Port name\n\n                        If a SectionName is specified, but does not exist on the targeted object,\n                        the Policy must fail to attach, and the policy implementation should record\n                        a `ResolvedRefs` or similar Condition in the Policy's status.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - name\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when targetRefs includes\n                    2 or more references to the same target\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName\n                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))\n                    : true))'\n                - message: sectionName must be unique when targetRefs includes 2 or\n                    more references to the same target\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||\n                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              validation:\n                description: Validation contains backend TLS validation configuration.\n                properties:\n                  caCertificateRefs:\n                    description: |-\n                      CACertificateRefs contains one or more references to Kubernetes objects that\n                      contain a PEM-encoded TLS CA certificate bundle, which is used to\n                      validate a TLS handshake between the Gateway and backend Pod.\n\n                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be\n                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,\n                      not both. If CACertificateRefs is empty or unspecified, the configuration for\n                      WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\n                      A CACertificateRef is invalid if:\n\n                      * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key\n                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`\n                        and the Message of the Condition must indicate which reference is invalid and why.\n\n                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason\n                        must be set to `InvalidKind` and the Message of the Condition must explain which\n                        kind of resource is unknown or unsupported.\n\n                      * It refers to a resource in another namespace. This may change in future\n                        spec updates.\n\n                      Implementations MAY choose to perform further validation of the certificate\n                      content (e.g., checking expiry or enforcing specific formats). In such cases,\n                      an implementation-specific Reason and Message must be set for the invalid reference.\n\n                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on\n                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message\n                      that indicate the cause of the error. Connections using an invalid\n                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error\n                      response. If ALL CACertificateRefs are invalid, the implementation MUST also\n                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to\n                      `status: False`, with a Reason `NoValidCACertificate`.\n\n                      A single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support.\n                      Implementations MAY choose to support attaching multiple certificates to\n                      a backend, but this behavior is implementation-specific.\n\n                      Support: Core - An optional single reference to a Kubernetes ConfigMap,\n                      with the CA certificate in a key named `ca.crt`.\n\n                      Support: Implementation-specific - More than one reference, other kinds\n                      of resources, or a single reference that includes multiple certificates.\n                    items:\n                      description: |-\n                        LocalObjectReference identifies an API object within the namespace of the\n                        referrer.\n                        The API object must be valid in the cluster; the Group and Kind must\n                        be registered in the cluster for this reference to be valid.\n\n                        References to objects with invalid Group and Kind are not valid, and must\n                        be rejected by the implementation, with appropriate Conditions set\n                        on the containing object.\n                      properties:\n                        group:\n                          description: |-\n                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                            When unspecified or empty string, core API group is inferred.\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          description: Kind is kind of the referent. For example \"HTTPRoute\"\n                            or \"Service\".\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: Name is the name of the referent.\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                      required:\n                      - group\n                      - kind\n                      - name\n                      type: object\n                    maxItems: 8\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  hostname:\n                    description: |-\n                      Hostname is used for two purposes in the connection between Gateways and\n                      backends:\n\n                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).\n                      2. Hostname MUST be used for authentication and MUST match the certificate\n                         served by the matching backend, unless SubjectAltNames is specified.\n                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection\n                         but MUST NOT be used for authentication. If you want to use the value\n                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.\n\n                      Support: Core\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  subjectAltNames:\n                    description: |-\n                      SubjectAltNames contains one or more Subject Alternative Names.\n                      When specified the certificate served from the backend MUST\n                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\n                      Support: Extended\n                    items:\n                      description: SubjectAltName represents Subject Alternative Name.\n                      properties:\n                        hostname:\n                          description: |-\n                            Hostname contains Subject Alternative Name specified in DNS name format.\n                            Required when Type is set to Hostname, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        type:\n                          description: |-\n                            Type determines the format of the Subject Alternative Name. Always required.\n\n                            Support: Core\n                          enum:\n                          - Hostname\n                          - URI\n                          type: string\n                        uri:\n                          description: |-\n                            URI contains Subject Alternative Name specified in a full URI format.\n                            It MUST include both a scheme (e.g., \"http\" or \"ftp\") and a scheme-specific-part.\n                            Common values include SPIFFE IDs like \"spiffe://mycluster.example.com/ns/myns/sa/svc1sa\".\n                            Required when Type is set to URI, ignored otherwise.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\\?([^#]*))?(#(.*))?\n                          type: string\n                      required:\n                      - type\n                      type: object\n                      x-kubernetes-validations:\n                      - message: SubjectAltName element must contain Hostname, if\n                          Type is set to Hostname\n                        rule: '!(self.type == \"Hostname\" && (!has(self.hostname) ||\n                          self.hostname == \"\"))'\n                      - message: SubjectAltName element must not contain Hostname,\n                          if Type is not set to Hostname\n                        rule: '!(self.type != \"Hostname\" && has(self.hostname) &&\n                          self.hostname != \"\")'\n                      - message: SubjectAltName element must contain URI, if Type\n                          is set to URI\n                        rule: '!(self.type == \"URI\" && (!has(self.uri) || self.uri\n                          == \"\"))'\n                      - message: SubjectAltName element must not contain URI, if Type\n                          is not set to URI\n                        rule: '!(self.type != \"URI\" && has(self.uri) && self.uri !=\n                          \"\")'\n                    maxItems: 5\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  wellKnownCACertificates:\n                    description: |-\n                      WellKnownCACertificates specifies whether a well-known set of CA certificates\n                      may be used in the TLS handshake between the gateway and backend pod.\n\n                      If WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs\n                      must be specified with at least one entry for a valid configuration. Only one of\n                      CACertificateRefs or WellKnownCACertificates may be specified, not both.\n                      If an implementation does not support the WellKnownCACertificates field, or\n                      the supplied value is not recognized, the implementation MUST ensure the\n                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with\n                      a Reason `Invalid`.\n\n                      Valid values include:\n                      * \"System\" - indicates that well-known system CA certificates should be used.\n\n                      Implementations MAY define their own sets of CA certificates. Such definitions\n                      MUST use an implementation-specific, prefixed name, such as\n                      `mycompany.com/my-custom-ca-certifcates`.\n\n                      Support: Implementation-specific\n                    maxLength: 253\n                    minLength: 1\n                    pattern: ^(System|([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]))$\n                    type: string\n                required:\n                - hostname\n                type: object\n                x-kubernetes-validations:\n                - message: must not contain both CACertificateRefs and WellKnownCACertificates\n                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")'\n                - message: must specify either CACertificateRefs or WellKnownCACertificates\n                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)\n                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates\n                    != \"\")\n            required:\n            - targetRefs\n            - validation\n            type: object\n          status:\n            description: Status defines the current state of BackendTLSPolicy.\n            properties:\n              ancestors:\n                description: |-\n                  Ancestors is a list of ancestor resources (usually Gateways) that are\n                  associated with the policy, and the status of the policy with respect to\n                  each ancestor. When this policy attaches to a parent, the controller that\n                  manages the parent and the ancestors MUST add an entry to this list when\n                  the controller first sees the policy and SHOULD update the entry as\n                  appropriate when the relevant ancestor is modified.\n\n                  Note that choosing the relevant ancestor is left to the Policy designers;\n                  an important part of Policy design is designing the right object level at\n                  which to namespace this status.\n\n                  Note also that implementations MUST ONLY populate ancestor status for\n                  the Ancestor resources they are responsible for. Implementations MUST\n                  use the ControllerName field to uniquely identify the entries in this list\n                  that they are responsible for.\n\n                  Note that to achieve this, the list of PolicyAncestorStatus structs\n                  MUST be treated as a map with a composite key, made up of the AncestorRef\n                  and ControllerName fields combined.\n\n                  A maximum of 16 ancestors will be represented in this list. An empty list\n                  means the Policy is not relevant for any ancestors.\n\n                  If this slice is full, implementations MUST NOT add further entries.\n                  Instead they MUST consider the policy unimplementable and signal that\n                  on any related resources such as the ancestor that would be referenced\n                  here. For example, if this list was full on BackendTLSPolicy, no\n                  additional Gateways would be able to reference the Service targeted by\n                  the BackendTLSPolicy.\n                items:\n                  description: |-\n                    PolicyAncestorStatus describes the status of a route with respect to an\n                    associated Ancestor.\n\n                    Ancestors refer to objects that are either the Target of a policy or above it\n                    in terms of object hierarchy. For example, if a policy targets a Service, the\n                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and\n                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most\n                    useful object to place Policy status on, so we recommend that implementations\n                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers\n                    have a _very_ good reason otherwise.\n\n                    In the context of policy attachment, the Ancestor is used to distinguish which\n                    resource results in a distinct application of this policy. For example, if a policy\n                    targets a Service, it may have a distinct result per attached Gateway.\n\n                    Policies targeting the same resource may have different effects depending on the\n                    ancestors of those resources. For example, different Gateways targeting the same\n                    Service may have different capabilities, especially if they have different underlying\n                    implementations.\n\n                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is\n                    used as a backend in a HTTPRoute that is itself attached to a Gateway.\n                    In this case, the relevant object for status is the Gateway, and that is the\n                    ancestor object referred to in this status.\n\n                    Note that a parent is also an ancestor, so for objects where the parent is the\n                    relevant object for status, this struct SHOULD still be used.\n\n                    This struct is intended to be used in a slice that's effectively a map,\n                    with a composite key made up of the AncestorRef and the ControllerName.\n                  properties:\n                    ancestorRef:\n                      description: |-\n                        AncestorRef corresponds with a ParentRef in the spec that this\n                        PolicyAncestorStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    conditions:\n                      description: Conditions describes the status of the Policy with\n                        respect to the given Ancestor.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                  required:\n                  - ancestorRef\n                  - conditions\n                  - controllerName\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - ancestors\n            type: object\n        required:\n        - spec\n        type: object\n    served: false\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_gatewayclasses.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: gatewayclasses.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: GatewayClass\n    listKind: GatewayClassList\n    plural: gatewayclasses\n    shortNames:\n    - gc\n    singular: gatewayclass\n  scope: Cluster\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.controllerName\n      name: Controller\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - jsonPath: .spec.description\n      name: Description\n      priority: 1\n      type: string\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          GatewayClass describes a class of Gateways available to the user for creating\n          Gateway resources.\n\n          It is recommended that this resource be used as a template for Gateways. This\n          means that a Gateway is based on the state of the GatewayClass at the time it\n          was created and changes to the GatewayClass or associated parameters are not\n          propagated down to existing Gateways. This recommendation is intended to\n          limit the blast radius of changes to GatewayClass or associated parameters.\n          If implementations choose to propagate GatewayClass changes to existing\n          Gateways, that MUST be clearly documented by the implementation.\n\n          Whenever one or more Gateways are using a GatewayClass, implementations SHOULD\n          add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the\n          associated GatewayClass. This ensures that a GatewayClass associated with a\n          Gateway is not deleted while in use.\n\n          GatewayClass is a Cluster level resource.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of GatewayClass.\n            properties:\n              controllerName:\n                description: |-\n                  ControllerName is the name of the controller that is managing Gateways of\n                  this class. The value of this field MUST be a domain prefixed path.\n\n                  Example: \"example.net/gateway-controller\".\n\n                  This field is not mutable and cannot be empty.\n\n                  Support: Core\n                maxLength: 253\n                minLength: 1\n                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                type: string\n                x-kubernetes-validations:\n                - message: Value is immutable\n                  rule: self == oldSelf\n              description:\n                description: Description helps describe a GatewayClass with more details.\n                maxLength: 64\n                type: string\n              parametersRef:\n                description: |-\n                  ParametersRef is a reference to a resource that contains the configuration\n                  parameters corresponding to the GatewayClass. This is optional if the\n                  controller does not require any additional configuration.\n\n                  ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,\n                  or an implementation-specific custom resource. The resource can be\n                  cluster-scoped or namespace-scoped.\n\n                  If the referent cannot be found, refers to an unsupported kind, or when\n                  the data within that resource is malformed, the GatewayClass SHOULD be\n                  rejected with the \"Accepted\" status condition set to \"False\" and an\n                  \"InvalidParameters\" reason.\n\n                  A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,\n                  the merging behavior is implementation specific.\n                  It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                  Support: Implementation-specific\n                properties:\n                  group:\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    description: Kind is kind of the referent.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.\n                      This field is required when referring to a Namespace-scoped resource and\n                      MUST be unset when referring to a Cluster-scoped resource.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - group\n                - kind\n                - name\n                type: object\n            required:\n            - controllerName\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n            description: |-\n              Status defines the current state of GatewayClass.\n\n              Implementations MUST populate status on all GatewayClass resources which\n              specify their controller name.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                description: |-\n                  Conditions is the current status from the controller for\n                  this GatewayClass.\n\n                  Controllers should prefer to publish conditions using values\n                  of GatewayClassConditionType for the type of each Condition.\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              supportedFeatures:\n                description: |-\n                  SupportedFeatures is the set of features the GatewayClass support.\n                  It MUST be sorted in ascending alphabetical order by the Name key.\n                items:\n                  properties:\n                    name:\n                      description: |-\n                        FeatureName is used to describe distinct features that are covered by\n                        conformance tests.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .spec.controllerName\n      name: Controller\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - jsonPath: .spec.description\n      name: Description\n      priority: 1\n      type: string\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          GatewayClass describes a class of Gateways available to the user for creating\n          Gateway resources.\n\n          It is recommended that this resource be used as a template for Gateways. This\n          means that a Gateway is based on the state of the GatewayClass at the time it\n          was created and changes to the GatewayClass or associated parameters are not\n          propagated down to existing Gateways. This recommendation is intended to\n          limit the blast radius of changes to GatewayClass or associated parameters.\n          If implementations choose to propagate GatewayClass changes to existing\n          Gateways, that MUST be clearly documented by the implementation.\n\n          Whenever one or more Gateways are using a GatewayClass, implementations SHOULD\n          add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the\n          associated GatewayClass. This ensures that a GatewayClass associated with a\n          Gateway is not deleted while in use.\n\n          GatewayClass is a Cluster level resource.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of GatewayClass.\n            properties:\n              controllerName:\n                description: |-\n                  ControllerName is the name of the controller that is managing Gateways of\n                  this class. The value of this field MUST be a domain prefixed path.\n\n                  Example: \"example.net/gateway-controller\".\n\n                  This field is not mutable and cannot be empty.\n\n                  Support: Core\n                maxLength: 253\n                minLength: 1\n                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                type: string\n                x-kubernetes-validations:\n                - message: Value is immutable\n                  rule: self == oldSelf\n              description:\n                description: Description helps describe a GatewayClass with more details.\n                maxLength: 64\n                type: string\n              parametersRef:\n                description: |-\n                  ParametersRef is a reference to a resource that contains the configuration\n                  parameters corresponding to the GatewayClass. This is optional if the\n                  controller does not require any additional configuration.\n\n                  ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,\n                  or an implementation-specific custom resource. The resource can be\n                  cluster-scoped or namespace-scoped.\n\n                  If the referent cannot be found, refers to an unsupported kind, or when\n                  the data within that resource is malformed, the GatewayClass SHOULD be\n                  rejected with the \"Accepted\" status condition set to \"False\" and an\n                  \"InvalidParameters\" reason.\n\n                  A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,\n                  the merging behavior is implementation specific.\n                  It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                  Support: Implementation-specific\n                properties:\n                  group:\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    description: Kind is kind of the referent.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.\n                      This field is required when referring to a Namespace-scoped resource and\n                      MUST be unset when referring to a Cluster-scoped resource.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - group\n                - kind\n                - name\n                type: object\n            required:\n            - controllerName\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n            description: |-\n              Status defines the current state of GatewayClass.\n\n              Implementations MUST populate status on all GatewayClass resources which\n              specify their controller name.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                description: |-\n                  Conditions is the current status from the controller for\n                  this GatewayClass.\n\n                  Controllers should prefer to publish conditions using values\n                  of GatewayClassConditionType for the type of each Condition.\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              supportedFeatures:\n                description: |-\n                  SupportedFeatures is the set of features the GatewayClass support.\n                  It MUST be sorted in ascending alphabetical order by the Name key.\n                items:\n                  properties:\n                    name:\n                      description: |-\n                        FeatureName is used to describe distinct features that are covered by\n                        conformance tests.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_gateways.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: gateways.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: Gateway\n    listKind: GatewayList\n    plural: gateways\n    shortNames:\n    - gtw\n    singular: gateway\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.gatewayClassName\n      name: Class\n      type: string\n    - jsonPath: .status.addresses[*].value\n      name: Address\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          Gateway represents an instance of a service-traffic handling infrastructure\n          by binding Listeners to a set of IP addresses.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses requested for this Gateway. This is optional and behavior can\n                  depend on the implementation. If a value is set in the spec and the\n                  requested address is invalid or unavailable, the implementation MUST\n                  indicate this in an associated entry in GatewayStatus.Conditions.\n\n                  The Addresses field represents a request for the address(es) on the\n                  \"outside of the Gateway\", that traffic bound for this Gateway will use.\n                  This could be the IP address or hostname of an external load balancer or\n                  other networking infrastructure, or some other address that traffic will\n                  be sent to.\n\n                  If no Addresses are specified, the implementation MAY schedule the\n                  Gateway in an implementation-specific manner, assigning an appropriate\n                  set of Addresses.\n\n                  The implementation MUST bind all Listeners to every GatewayAddress that\n                  it assigns to the Gateway and add a corresponding entry in\n                  GatewayStatus.Addresses.\n\n                  Support: Extended\n                items:\n                  description: GatewaySpecAddress describes an address that can be\n                    bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        When a value is unspecified, an implementation SHOULD automatically\n                        assign an address matching the requested type if possible.\n\n                        If an implementation does not support an empty value, they MUST set the\n                        \"Programmed\" condition in status to False with a reason of \"AddressNotAssigned\".\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      type: string\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must be empty or contain only valid characters\n                      (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\")):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: IPAddress values must be unique\n                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n                - message: Hostname values must be unique\n                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n              allowedListeners:\n                description: |-\n                  AllowedListeners defines which ListenerSets can be attached to this Gateway.\n                  The default value is to allow no ListenerSets.\n                properties:\n                  namespaces:\n                    default:\n                      from: None\n                    description: |-\n                      Namespaces defines which namespaces ListenerSets can be attached to this Gateway.\n                      The default value is to allow no ListenerSets.\n                    properties:\n                      from:\n                        default: None\n                        description: |-\n                          From indicates where ListenerSets can attach to this Gateway. Possible\n                          values are:\n\n                          * Same: Only ListenerSets in the same namespace may be attached to this Gateway.\n                          * Selector: ListenerSets in namespaces selected by the selector may be attached to this Gateway.\n                          * All: ListenerSets in all namespaces may be attached to this Gateway.\n                          * None: Only listeners defined in the Gateway's spec are allowed\n\n                          The default value None\n                        enum:\n                        - All\n                        - Selector\n                        - Same\n                        - None\n                        type: string\n                      selector:\n                        description: |-\n                          Selector must be specified when From is set to \"Selector\". In that case,\n                          only ListenerSets in Namespaces matching this Selector will be selected by this\n                          Gateway. This field is ignored for other values of \"From\".\n                        properties:\n                          matchExpressions:\n                            description: matchExpressions is a list of label selector\n                              requirements. The requirements are ANDed.\n                            items:\n                              description: |-\n                                A label selector requirement is a selector that contains values, a key, and an operator that\n                                relates the key and values.\n                              properties:\n                                key:\n                                  description: key is the label key that the selector\n                                    applies to.\n                                  type: string\n                                operator:\n                                  description: |-\n                                    operator represents a key's relationship to a set of values.\n                                    Valid operators are In, NotIn, Exists and DoesNotExist.\n                                  type: string\n                                values:\n                                  description: |-\n                                    values is an array of string values. If the operator is In or NotIn,\n                                    the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                    the values array must be empty. This array is replaced during a strategic\n                                    merge patch.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              required:\n                              - key\n                              - operator\n                              type: object\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          matchLabels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                              map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                              operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                            type: object\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                type: object\n              gatewayClassName:\n                description: |-\n                  GatewayClassName used for this Gateway. This is the name of a\n                  GatewayClass resource.\n                maxLength: 253\n                minLength: 1\n                type: string\n              infrastructure:\n                description: |-\n                  Infrastructure defines infrastructure level attributes about this Gateway instance.\n\n                  Support: Extended\n                properties:\n                  annotations:\n                    additionalProperties:\n                      description: |-\n                        AnnotationValue is the value of an annotation in Gateway API. This is used\n                        for validation of maps such as TLS options. This roughly matches Kubernetes\n                        annotation validation, although the length validation in that case is based\n                        on the entire size of the annotations struct.\n                      maxLength: 4096\n                      minLength: 0\n                      type: string\n                    description: |-\n                      Annotations that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"annotations\" concepts.\n\n                      An implementation may chose to add additional implementation-specific annotations as they see fit.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Annotation keys must be in the form of an optional\n                        DNS subdomain prefix followed by a required name segment of\n                        up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the annotation key's prefix must be a\n                        DNS subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  labels:\n                    additionalProperties:\n                      description: |-\n                        LabelValue is the value of a label in the Gateway API. This is used for validation\n                        of maps such as Gateway infrastructure labels. This matches the Kubernetes\n                        label validation rules:\n                        * must be 63 characters or less (can be empty),\n                        * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]),\n                        * could contain dashes (-), underscores (_), dots (.), and alphanumerics between.\n\n                        Valid values include:\n\n                        * MyValue\n                        * my.name\n                        * 123-my-value\n                      maxLength: 63\n                      minLength: 0\n                      pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$\n                      type: string\n                    description: |-\n                      Labels that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"labels\" concepts.\n\n                      An implementation may chose to add additional implementation-specific labels as they see fit.\n\n                      If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels\n                      change, it SHOULD clearly warn about this behavior in documentation.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Label keys must be in the form of an optional DNS subdomain\n                        prefix followed by a required name segment of up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the label key's prefix must be a DNS\n                        subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  parametersRef:\n                    description: |-\n                      ParametersRef is a reference to a resource that contains the configuration\n                      parameters corresponding to the Gateway. This is optional if the\n                      controller does not require any additional configuration.\n\n                      This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis\n\n                      The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified,\n                      the merging behavior is implementation specific.\n                      It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                      If the referent cannot be found, refers to an unsupported kind, or when\n                      the data within that resource is malformed, the Gateway SHOULD be\n                      rejected with the \"Accepted\" status condition set to \"False\" and an\n                      \"InvalidParameters\" reason.\n\n                      Support: Implementation-specific\n                    properties:\n                      group:\n                        description: Group is the group of the referent.\n                        maxLength: 253\n                        pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                        type: string\n                      kind:\n                        description: Kind is kind of the referent.\n                        maxLength: 63\n                        minLength: 1\n                        pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                        type: string\n                      name:\n                        description: Name is the name of the referent.\n                        maxLength: 253\n                        minLength: 1\n                        type: string\n                    required:\n                    - group\n                    - kind\n                    - name\n                    type: object\n                type: object\n              listeners:\n                description: |-\n                  Listeners associated with this Gateway. Listeners define\n                  logical endpoints that are bound on this Gateway's addresses.\n                  At least one Listener MUST be specified.\n\n                  ## Distinct Listeners\n\n                  Each Listener in a set of Listeners (for example, in a single Gateway)\n                  MUST be _distinct_, in that a traffic flow MUST be able to be assigned to\n                  exactly one listener. (This section uses \"set of Listeners\" rather than\n                  \"Listeners in a single Gateway\" because implementations MAY merge configuration\n                  from multiple Gateways onto a single data plane, and these rules _also_\n                  apply in that case).\n\n                  Practically, this means that each listener in a set MUST have a unique\n                  combination of Port, Protocol, and, if supported by the protocol, Hostname.\n\n                  Some combinations of port, protocol, and TLS settings are considered\n                  Core support and MUST be supported by implementations based on the objects\n                  they support:\n\n                  HTTPRoute\n\n                  1. HTTPRoute, Port: 80, Protocol: HTTP\n                  2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided\n\n                  TLSRoute\n\n                  1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough\n\n                  \"Distinct\" Listeners have the following property:\n\n                  **The implementation can match inbound requests to a single distinct\n                  Listener**.\n\n                  When multiple Listeners share values for fields (for\n                  example, two Listeners with the same Port value), the implementation\n                  can match requests to only one of the Listeners using other\n                  Listener fields.\n\n                  When multiple listeners have the same value for the Protocol field, then\n                  each of the Listeners with matching Protocol values MUST have different\n                  values for other fields.\n\n                  The set of fields that MUST be different for a Listener differs per protocol.\n                  The following rules define the rules for what fields MUST be considered for\n                  Listeners to be distinct with each protocol currently defined in the\n                  Gateway API spec.\n\n                  The set of listeners that all share a protocol value MUST have _different_\n                  values for _at least one_ of these fields to be distinct:\n\n                  * **HTTP, HTTPS, TLS**: Port, Hostname\n                  * **TCP, UDP**: Port\n\n                  One **very** important rule to call out involves what happens when an\n                  implementation:\n\n                  * Supports TCP protocol Listeners, as well as HTTP, HTTPS, or TLS protocol\n                    Listeners, and\n                  * sees HTTP, HTTPS, or TLS protocols with the same `port` as one with TCP\n                    Protocol.\n\n                  In this case all the Listeners that share a port with the\n                  TCP Listener are not distinct and so MUST NOT be accepted.\n\n                  If an implementation does not support TCP Protocol Listeners, then the\n                  previous rule does not apply, and the TCP Listeners SHOULD NOT be\n                  accepted.\n\n                  Note that the `tls` field is not used for determining if a listener is distinct, because\n                  Listeners that _only_ differ on TLS config will still conflict in all cases.\n\n                  ### Listeners that are distinct only by Hostname\n\n                  When the Listeners are distinct based only on Hostname, inbound request\n                  hostnames MUST match from the most specific to least specific Hostname\n                  values to choose the correct Listener and its associated set of Routes.\n\n                  Exact matches MUST be processed before wildcard matches, and wildcard\n                  matches MUST be processed before fallback (empty Hostname value)\n                  matches. For example, `\"foo.example.com\"` takes precedence over\n                  `\"*.example.com\"`, and `\"*.example.com\"` takes precedence over `\"\"`.\n\n                  Additionally, if there are multiple wildcard entries, more specific\n                  wildcard entries must be processed before less specific wildcard entries.\n                  For example, `\"*.foo.example.com\"` takes precedence over `\"*.example.com\"`.\n\n                  The precise definition here is that the higher the number of dots in the\n                  hostname to the right of the wildcard character, the higher the precedence.\n\n                  The wildcard character will match any number of characters _and dots_ to\n                  the left, however, so `\"*.example.com\"` will match both\n                  `\"foo.bar.example.com\"` _and_ `\"bar.example.com\"`.\n\n                  ## Handling indistinct Listeners\n\n                  If a set of Listeners contains Listeners that are not distinct, then those\n                  Listeners are _Conflicted_, and the implementation MUST set the \"Conflicted\"\n                  condition in the Listener Status to \"True\".\n\n                  The words \"indistinct\" and \"conflicted\" are considered equivalent for the\n                  purpose of this documentation.\n\n                  Implementations MAY choose to accept a Gateway with some Conflicted\n                  Listeners only if they only accept the partial Listener set that contains\n                  no Conflicted Listeners.\n\n                  Specifically, an implementation MAY accept a partial Listener set subject to\n                  the following rules:\n\n                  * The implementation MUST NOT pick one conflicting Listener as the winner.\n                    ALL indistinct Listeners must not be accepted for processing.\n                  * At least one distinct Listener MUST be present, or else the Gateway effectively\n                    contains _no_ Listeners, and must be rejected from processing as a whole.\n\n                  The implementation MUST set a \"ListenersNotValid\" condition on the\n                  Gateway Status when the Gateway contains Conflicted Listeners whether or\n                  not they accept the Gateway. That Condition SHOULD clearly\n                  indicate in the Message which Listeners are conflicted, and which are\n                  Accepted. Additionally, the Listener status for those listeners SHOULD\n                  indicate which Listeners are conflicted and not Accepted.\n\n                  ## General Listener behavior\n\n                  Note that, for all distinct Listeners, requests SHOULD match at most one Listener.\n                  For example, if Listeners are defined for \"foo.example.com\" and \"*.example.com\", a\n                  request to \"foo.example.com\" SHOULD only be routed using routes attached\n                  to the \"foo.example.com\" Listener (and not the \"*.example.com\" Listener).\n\n                  This concept is known as \"Listener Isolation\", and it is an Extended feature\n                  of Gateway API. Implementations that do not support Listener Isolation MUST\n                  clearly document this, and MUST NOT claim support for the\n                  `GatewayHTTPListenerIsolation` feature.\n\n                  Implementations that _do_ support Listener Isolation SHOULD claim support\n                  for the Extended `GatewayHTTPListenerIsolation` feature and pass the associated\n                  conformance tests.\n\n                  ## Compatible Listeners\n\n                  A Gateway's Listeners are considered _compatible_ if:\n\n                  1. They are distinct.\n                  2. The implementation can serve them in compliance with the Addresses\n                     requirement that all Listeners are available on all assigned\n                     addresses.\n\n                  Compatible combinations in Extended support are expected to vary across\n                  implementations. A combination that is compatible for one implementation\n                  may not be compatible for another.\n\n                  For example, an implementation that cannot serve both TCP and UDP listeners\n                  on the same address, or cannot mix HTTPS and generic TLS listens on the same port\n                  would not consider those cases compatible, even though they are distinct.\n\n                  Implementations MAY merge separate Gateways onto a single set of\n                  Addresses if all Listeners across all Gateways are compatible.\n\n                  In a future release the MinItems=1 requirement MAY be dropped.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Listener embodies the concept of a logical endpoint where a Gateway accepts\n                    network connections.\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n\n                        Support: Core\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n                          Note that this does not require the SNI and Host header to be the same.\n                          The semantics of this are described in more detail below.\n\n                        To ensure security, Section 11.1 of RFC-6066 emphasizes that server\n                        implementations that rely on SNI hostname matching MUST also verify\n                        hostnames within the application protocol.\n\n                        Section 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\n                        reuse of a connection by responding with the HTTP 421 Misdirected Request\n                        status code. This indicates that the origin server has rejected the\n                        request because it appears to have been misdirected.\n\n                        To detect misdirected requests, Gateways SHOULD match the authority of\n                        the requests with all the SNI hostname(s) configured across all the\n                        Gateway Listeners on the same port and protocol:\n\n                        * If another Listener has an exact match or more specific wildcard entry,\n                          the Gateway SHOULD return a 421.\n                        * If the current Listener (selected by SNI matching during ClientHello)\n                          does not match the Host:\n                            * If another Listener does match the Host, the Gateway SHOULD return a\n                              421.\n                            * If no other Listener matches the Host, the Gateway MUST return a\n                              404.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n\n                        Support: Core\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    protocol:\n                      description: |-\n                        Protocol specifies the network protocol this listener expects to receive.\n\n                        Support: Core\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n\n                        Support: Core\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - port\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: tls mode must be set for protocol TLS\n                  rule: 'self.all(l, (l.protocol == ''TLS'' ? has(l.tls) && has(l.tls.mode)\n                    && l.tls.mode != '''' : true))'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol\n                    == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname\n                    == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'\n              tls:\n                description: |-\n                  TLS specifies frontend and backend tls configuration for entire gateway.\n\n                  Support: Extended\n                properties:\n                  backend:\n                    description: |-\n                      Backend describes TLS configuration for gateway when connecting\n                      to backends.\n\n                      Note that this contains only details for the Gateway as a TLS client,\n                      and does _not_ imply behavior about how to choose which backend should\n                      get a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\n                      Support: Core\n                    properties:\n                      clientCertificateRef:\n                        description: |-\n                          ClientCertificateRef references an object that contains a client certificate\n                          and its associated private key. It can reference standard Kubernetes resources,\n                          i.e., Secret, or implementation-specific custom resources.\n\n                          A ClientCertificateRef is considered invalid if:\n\n                          * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                            does not exist) or is misconfigured (e.g., a Secret does not contain the keys\n                            named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef`\n                            and the Message of the Condition MUST indicate why the reference is invalid.\n\n                          * It refers to a resource in another namespace UNLESS there is a ReferenceGrant\n                            in the target namespace that allows the certificate to be attached.\n                            If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `RefNotPermitted`.\n\n                          Implementations MAY choose to perform further validation of the certificate\n                          content (e.g., checking expiry or enforcing specific formats). In such cases,\n                          an implementation-specific Reason and Message MUST be set.\n\n                          Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`).\n                          Support: Implementation-specific - Other resource kinds or Secrets with a\n                          different type (e.g., `Opaque`).\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Secret\n                            description: Kind is kind of the referent. For example\n                              \"Secret\".\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the referenced object. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                        required:\n                        - name\n                        type: object\n                    type: object\n                  frontend:\n                    description: |-\n                      Frontend describes TLS config when client connects to Gateway.\n                      Support: Core\n                    properties:\n                      default:\n                        description: |-\n                          Default specifies the default client certificate validation configuration\n                          for all Listeners handling HTTPS traffic, unless a per-port configuration\n                          is defined.\n\n                          support: Core\n                        properties:\n                          validation:\n                            description: |-\n                              Validation holds configuration information for validating the frontend (client).\n                              Setting this field will result in mutual authentication when connecting to the gateway.\n                              In browsers this may result in a dialog appearing\n                              that requests a user to specify the client certificate.\n                              The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                              Support: Core\n                            properties:\n                              caCertificateRefs:\n                                description: |-\n                                  CACertificateRefs contains one or more references to Kubernetes\n                                  objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                  is used as a trust anchor to validate the certificates presented by\n                                  the client.\n\n                                  A CACertificateRef is invalid if:\n\n                                  * It refers to a resource that cannot be resolved (e.g., the\n                                    referenced resource does not exist) or is misconfigured (e.g., a\n                                    ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                    Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                    and the Message of the Condition must indicate which reference is invalid and why.\n\n                                  * It refers to an unknown or unsupported kind of resource. In this\n                                    case, the Reason on all matching HTTPS listeners must be set to\n                                    `InvalidCACertificateKind` and the Message of the Condition must explain\n                                    which kind of resource is unknown or unsupported.\n\n                                  * It refers to a resource in another namespace UNLESS there is a\n                                    ReferenceGrant in the target namespace that allows the CA\n                                    certificate to be attached. If a ReferenceGrant does not allow this\n                                    reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                    MUST be set with the Reason `RefNotPermitted`.\n\n                                  Implementations MAY choose to perform further validation of the\n                                  certificate content (e.g., checking expiry or enforcing specific formats).\n                                  In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                  In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                  condition is set to `status: False` on all targeted listeners (i.e.,\n                                  listeners serving HTTPS on a matching port). The condition MUST\n                                  include a Reason and Message that indicate the cause of the error. If\n                                  ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                  the `Accepted` condition on the listener is set to `status: False`, with\n                                  the Reason `NoValidCACertificate`.\n                                  Implementations MAY choose to support attaching multiple CA certificates\n                                  to a listener, but this behavior is implementation-specific.\n\n                                  Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                  CA certificate in a key named `ca.crt`.\n\n                                  Support: Implementation-specific - More than one reference, other kinds\n                                  of resources, or a single reference that includes multiple certificates.\n                                items:\n                                  description: |-\n                                    ObjectReference identifies an API object including its namespace.\n\n                                    The API object must be valid in the cluster; the Group and Kind must\n                                    be registered in the cluster for this reference to be valid.\n\n                                    References to objects with invalid Group and Kind are not valid, and must\n                                    be rejected by the implementation, with appropriate Conditions set\n                                    on the containing object.\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When set to the empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"ConfigMap\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of the referenced object. When unspecified, the local\n                                        namespace is inferred.\n\n                                        Note that when a namespace different than the local namespace is specified,\n                                        a ReferenceGrant object is required in the referent namespace to allow that\n                                        namespace's owner to accept the reference. See the ReferenceGrant\n                                        documentation for details.\n\n                                        Support: Core\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                maxItems: 8\n                                minItems: 1\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              mode:\n                                default: AllowValidOnly\n                                description: |-\n                                  FrontendValidationMode defines the mode for validating the client certificate.\n                                  There are two possible modes:\n\n                                  - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                    the client presents a valid certificate. This certificate must successfully\n                                    pass validation against the CA certificates specified in `CACertificateRefs`.\n                                  - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                    even if the client certificate is not presented or fails verification.\n\n                                    This approach delegates client authorization to the backend and introduce\n                                    a significant security risk. It should be used in testing environments or\n                                    on a temporary basis in non-testing environments.\n\n                                  Defaults to AllowValidOnly.\n\n                                  Support: Core\n                                enum:\n                                - AllowValidOnly\n                                - AllowInsecureFallback\n                                type: string\n                            required:\n                            - caCertificateRefs\n                            type: object\n                        type: object\n                      perPort:\n                        description: |-\n                          PerPort specifies tls configuration assigned per port.\n                          Per port configuration is optional. Once set this configuration overrides\n                          the default configuration for all Listeners handling HTTPS traffic\n                          that match this port.\n                          Each override port requires a unique TLS configuration.\n\n                          support: Core\n                        items:\n                          properties:\n                            port:\n                              description: |-\n                                The Port indicates the Port Number to which the TLS configuration will be\n                                applied. This configuration will be applied to all Listeners handling HTTPS\n                                traffic that match this port.\n\n                                Support: Core\n                              format: int32\n                              maximum: 65535\n                              minimum: 1\n                              type: integer\n                            tls:\n                              description: |-\n                                TLS store the configuration that will be applied to all Listeners handling\n                                HTTPS traffic and matching given port.\n\n                                Support: Core\n                              properties:\n                                validation:\n                                  description: |-\n                                    Validation holds configuration information for validating the frontend (client).\n                                    Setting this field will result in mutual authentication when connecting to the gateway.\n                                    In browsers this may result in a dialog appearing\n                                    that requests a user to specify the client certificate.\n                                    The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                                    Support: Core\n                                  properties:\n                                    caCertificateRefs:\n                                      description: |-\n                                        CACertificateRefs contains one or more references to Kubernetes\n                                        objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                        is used as a trust anchor to validate the certificates presented by\n                                        the client.\n\n                                        A CACertificateRef is invalid if:\n\n                                        * It refers to a resource that cannot be resolved (e.g., the\n                                          referenced resource does not exist) or is misconfigured (e.g., a\n                                          ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                          Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                          and the Message of the Condition must indicate which reference is invalid and why.\n\n                                        * It refers to an unknown or unsupported kind of resource. In this\n                                          case, the Reason on all matching HTTPS listeners must be set to\n                                          `InvalidCACertificateKind` and the Message of the Condition must explain\n                                          which kind of resource is unknown or unsupported.\n\n                                        * It refers to a resource in another namespace UNLESS there is a\n                                          ReferenceGrant in the target namespace that allows the CA\n                                          certificate to be attached. If a ReferenceGrant does not allow this\n                                          reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                          MUST be set with the Reason `RefNotPermitted`.\n\n                                        Implementations MAY choose to perform further validation of the\n                                        certificate content (e.g., checking expiry or enforcing specific formats).\n                                        In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                        In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                        condition is set to `status: False` on all targeted listeners (i.e.,\n                                        listeners serving HTTPS on a matching port). The condition MUST\n                                        include a Reason and Message that indicate the cause of the error. If\n                                        ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                        the `Accepted` condition on the listener is set to `status: False`, with\n                                        the Reason `NoValidCACertificate`.\n                                        Implementations MAY choose to support attaching multiple CA certificates\n                                        to a listener, but this behavior is implementation-specific.\n\n                                        Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                        CA certificate in a key named `ca.crt`.\n\n                                        Support: Implementation-specific - More than one reference, other kinds\n                                        of resources, or a single reference that includes multiple certificates.\n                                      items:\n                                        description: |-\n                                          ObjectReference identifies an API object including its namespace.\n\n                                          The API object must be valid in the cluster; the Group and Kind must\n                                          be registered in the cluster for this reference to be valid.\n\n                                          References to objects with invalid Group and Kind are not valid, and must\n                                          be rejected by the implementation, with appropriate Conditions set\n                                          on the containing object.\n                                        properties:\n                                          group:\n                                            description: |-\n                                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                              When set to the empty string, core API group is inferred.\n                                            maxLength: 253\n                                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                            type: string\n                                          kind:\n                                            description: Kind is kind of the referent.\n                                              For example \"ConfigMap\" or \"Service\".\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                            type: string\n                                          name:\n                                            description: Name is the name of the referent.\n                                            maxLength: 253\n                                            minLength: 1\n                                            type: string\n                                          namespace:\n                                            description: |-\n                                              Namespace is the namespace of the referenced object. When unspecified, the local\n                                              namespace is inferred.\n\n                                              Note that when a namespace different than the local namespace is specified,\n                                              a ReferenceGrant object is required in the referent namespace to allow that\n                                              namespace's owner to accept the reference. See the ReferenceGrant\n                                              documentation for details.\n\n                                              Support: Core\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                            type: string\n                                        required:\n                                        - group\n                                        - kind\n                                        - name\n                                        type: object\n                                      maxItems: 8\n                                      minItems: 1\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    mode:\n                                      default: AllowValidOnly\n                                      description: |-\n                                        FrontendValidationMode defines the mode for validating the client certificate.\n                                        There are two possible modes:\n\n                                        - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                          the client presents a valid certificate. This certificate must successfully\n                                          pass validation against the CA certificates specified in `CACertificateRefs`.\n                                        - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                          even if the client certificate is not presented or fails verification.\n\n                                          This approach delegates client authorization to the backend and introduce\n                                          a significant security risk. It should be used in testing environments or\n                                          on a temporary basis in non-testing environments.\n\n                                        Defaults to AllowValidOnly.\n\n                                        Support: Core\n                                      enum:\n                                      - AllowValidOnly\n                                      - AllowInsecureFallback\n                                      type: string\n                                  required:\n                                  - caCertificateRefs\n                                  type: object\n                              type: object\n                          required:\n                          - port\n                          - tls\n                          type: object\n                        maxItems: 64\n                        type: array\n                        x-kubernetes-list-map-keys:\n                        - port\n                        x-kubernetes-list-type: map\n                        x-kubernetes-validations:\n                        - message: Port for TLS configuration must be unique within\n                            the Gateway\n                          rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))\n                    required:\n                    - default\n                    type: object\n                type: object\n            required:\n            - gatewayClassName\n            - listeners\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses lists the network addresses that have been bound to the\n                  Gateway.\n\n                  This list may differ from the addresses provided in the spec under some\n                  conditions:\n\n                    * no addresses are specified, all addresses are dynamically assigned\n                    * a combination of specified and dynamic addresses are assigned\n                    * a specified address was unusable (e.g. already in use)\n                items:\n                  description: GatewayStatusAddress describes a network address that\n                    is bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        Value of the address. The validity of the values will depend\n                        on the type and support by the controller.\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - value\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must only contain valid characters (matching\n                      ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    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])?)*$\"\"\"):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              attachedListenerSets:\n                description: |-\n                  AttachedListenerSets represents the total number of ListenerSets that have been\n                  successfully attached to this Gateway.\n\n                  A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n                  - The ListenerSet is selected by the Gateway's AllowedListeners field\n                  - The ListenerSet has a valid ParentRef selecting the Gateway\n                  - The ListenerSet's status has the condition \"Accepted: true\"\n\n                  Uses for this field include troubleshooting AttachedListenerSets attachment and\n                  measuring blast radius/impact of changes to a Gateway.\n                format: int32\n                type: integer\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the Gateway.\n\n                  Implementations should prefer to express Gateway conditions\n                  using the `GatewayConditionType` and `GatewayConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe Gateway state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                  * \"Ready\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener or Route status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners, even if the Accepted condition of an individual Listener is set\n                        to \"False\". The AttachedRoutes number represents the number of Routes with\n                        the Accepted condition set to \"True\" that have been attached to this Listener.\n                        Routes with any other value for the Accepted condition MUST NOT be included\n                        in this count.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds supported by an implementation for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .spec.gatewayClassName\n      name: Class\n      type: string\n    - jsonPath: .status.addresses[*].value\n      name: Address\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          Gateway represents an instance of a service-traffic handling infrastructure\n          by binding Listeners to a set of IP addresses.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses requested for this Gateway. This is optional and behavior can\n                  depend on the implementation. If a value is set in the spec and the\n                  requested address is invalid or unavailable, the implementation MUST\n                  indicate this in an associated entry in GatewayStatus.Conditions.\n\n                  The Addresses field represents a request for the address(es) on the\n                  \"outside of the Gateway\", that traffic bound for this Gateway will use.\n                  This could be the IP address or hostname of an external load balancer or\n                  other networking infrastructure, or some other address that traffic will\n                  be sent to.\n\n                  If no Addresses are specified, the implementation MAY schedule the\n                  Gateway in an implementation-specific manner, assigning an appropriate\n                  set of Addresses.\n\n                  The implementation MUST bind all Listeners to every GatewayAddress that\n                  it assigns to the Gateway and add a corresponding entry in\n                  GatewayStatus.Addresses.\n\n                  Support: Extended\n                items:\n                  description: GatewaySpecAddress describes an address that can be\n                    bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        When a value is unspecified, an implementation SHOULD automatically\n                        assign an address matching the requested type if possible.\n\n                        If an implementation does not support an empty value, they MUST set the\n                        \"Programmed\" condition in status to False with a reason of \"AddressNotAssigned\".\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      type: string\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must be empty or contain only valid characters\n                      (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\")):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: IPAddress values must be unique\n                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n                - message: Hostname values must be unique\n                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?\n                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value\n                    == a1.value) : true )'\n              allowedListeners:\n                description: |-\n                  AllowedListeners defines which ListenerSets can be attached to this Gateway.\n                  The default value is to allow no ListenerSets.\n                properties:\n                  namespaces:\n                    default:\n                      from: None\n                    description: |-\n                      Namespaces defines which namespaces ListenerSets can be attached to this Gateway.\n                      The default value is to allow no ListenerSets.\n                    properties:\n                      from:\n                        default: None\n                        description: |-\n                          From indicates where ListenerSets can attach to this Gateway. Possible\n                          values are:\n\n                          * Same: Only ListenerSets in the same namespace may be attached to this Gateway.\n                          * Selector: ListenerSets in namespaces selected by the selector may be attached to this Gateway.\n                          * All: ListenerSets in all namespaces may be attached to this Gateway.\n                          * None: Only listeners defined in the Gateway's spec are allowed\n\n                          The default value None\n                        enum:\n                        - All\n                        - Selector\n                        - Same\n                        - None\n                        type: string\n                      selector:\n                        description: |-\n                          Selector must be specified when From is set to \"Selector\". In that case,\n                          only ListenerSets in Namespaces matching this Selector will be selected by this\n                          Gateway. This field is ignored for other values of \"From\".\n                        properties:\n                          matchExpressions:\n                            description: matchExpressions is a list of label selector\n                              requirements. The requirements are ANDed.\n                            items:\n                              description: |-\n                                A label selector requirement is a selector that contains values, a key, and an operator that\n                                relates the key and values.\n                              properties:\n                                key:\n                                  description: key is the label key that the selector\n                                    applies to.\n                                  type: string\n                                operator:\n                                  description: |-\n                                    operator represents a key's relationship to a set of values.\n                                    Valid operators are In, NotIn, Exists and DoesNotExist.\n                                  type: string\n                                values:\n                                  description: |-\n                                    values is an array of string values. If the operator is In or NotIn,\n                                    the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                    the values array must be empty. This array is replaced during a strategic\n                                    merge patch.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              required:\n                              - key\n                              - operator\n                              type: object\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          matchLabels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                              map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                              operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                            type: object\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                type: object\n              gatewayClassName:\n                description: |-\n                  GatewayClassName used for this Gateway. This is the name of a\n                  GatewayClass resource.\n                maxLength: 253\n                minLength: 1\n                type: string\n              infrastructure:\n                description: |-\n                  Infrastructure defines infrastructure level attributes about this Gateway instance.\n\n                  Support: Extended\n                properties:\n                  annotations:\n                    additionalProperties:\n                      description: |-\n                        AnnotationValue is the value of an annotation in Gateway API. This is used\n                        for validation of maps such as TLS options. This roughly matches Kubernetes\n                        annotation validation, although the length validation in that case is based\n                        on the entire size of the annotations struct.\n                      maxLength: 4096\n                      minLength: 0\n                      type: string\n                    description: |-\n                      Annotations that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"annotations\" concepts.\n\n                      An implementation may chose to add additional implementation-specific annotations as they see fit.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Annotation keys must be in the form of an optional\n                        DNS subdomain prefix followed by a required name segment of\n                        up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the annotation key's prefix must be a\n                        DNS subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  labels:\n                    additionalProperties:\n                      description: |-\n                        LabelValue is the value of a label in the Gateway API. This is used for validation\n                        of maps such as Gateway infrastructure labels. This matches the Kubernetes\n                        label validation rules:\n                        * must be 63 characters or less (can be empty),\n                        * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]),\n                        * could contain dashes (-), underscores (_), dots (.), and alphanumerics between.\n\n                        Valid values include:\n\n                        * MyValue\n                        * my.name\n                        * 123-my-value\n                      maxLength: 63\n                      minLength: 0\n                      pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$\n                      type: string\n                    description: |-\n                      Labels that SHOULD be applied to any resources created in response to this Gateway.\n\n                      For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources.\n                      For other implementations, this refers to any relevant (implementation specific) \"labels\" concepts.\n\n                      An implementation may chose to add additional implementation-specific labels as they see fit.\n\n                      If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels\n                      change, it SHOULD clearly warn about this behavior in documentation.\n\n                      Support: Extended\n                    maxProperties: 8\n                    type: object\n                    x-kubernetes-validations:\n                    - message: Label keys must be in the form of an optional DNS subdomain\n                        prefix followed by a required name segment of up to 63 characters.\n                      rule: self.all(key, key.matches(r\"\"\"^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$\"\"\"))\n                    - message: If specified, the label key's prefix must be a DNS\n                        subdomain not longer than 253 characters in total.\n                      rule: self.all(key, key.split(\"/\")[0].size() < 253)\n                  parametersRef:\n                    description: |-\n                      ParametersRef is a reference to a resource that contains the configuration\n                      parameters corresponding to the Gateway. This is optional if the\n                      controller does not require any additional configuration.\n\n                      This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis\n\n                      The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified,\n                      the merging behavior is implementation specific.\n                      It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.\n\n                      If the referent cannot be found, refers to an unsupported kind, or when\n                      the data within that resource is malformed, the Gateway SHOULD be\n                      rejected with the \"Accepted\" status condition set to \"False\" and an\n                      \"InvalidParameters\" reason.\n\n                      Support: Implementation-specific\n                    properties:\n                      group:\n                        description: Group is the group of the referent.\n                        maxLength: 253\n                        pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                        type: string\n                      kind:\n                        description: Kind is kind of the referent.\n                        maxLength: 63\n                        minLength: 1\n                        pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                        type: string\n                      name:\n                        description: Name is the name of the referent.\n                        maxLength: 253\n                        minLength: 1\n                        type: string\n                    required:\n                    - group\n                    - kind\n                    - name\n                    type: object\n                type: object\n              listeners:\n                description: |-\n                  Listeners associated with this Gateway. Listeners define\n                  logical endpoints that are bound on this Gateway's addresses.\n                  At least one Listener MUST be specified.\n\n                  ## Distinct Listeners\n\n                  Each Listener in a set of Listeners (for example, in a single Gateway)\n                  MUST be _distinct_, in that a traffic flow MUST be able to be assigned to\n                  exactly one listener. (This section uses \"set of Listeners\" rather than\n                  \"Listeners in a single Gateway\" because implementations MAY merge configuration\n                  from multiple Gateways onto a single data plane, and these rules _also_\n                  apply in that case).\n\n                  Practically, this means that each listener in a set MUST have a unique\n                  combination of Port, Protocol, and, if supported by the protocol, Hostname.\n\n                  Some combinations of port, protocol, and TLS settings are considered\n                  Core support and MUST be supported by implementations based on the objects\n                  they support:\n\n                  HTTPRoute\n\n                  1. HTTPRoute, Port: 80, Protocol: HTTP\n                  2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided\n\n                  TLSRoute\n\n                  1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough\n\n                  \"Distinct\" Listeners have the following property:\n\n                  **The implementation can match inbound requests to a single distinct\n                  Listener**.\n\n                  When multiple Listeners share values for fields (for\n                  example, two Listeners with the same Port value), the implementation\n                  can match requests to only one of the Listeners using other\n                  Listener fields.\n\n                  When multiple listeners have the same value for the Protocol field, then\n                  each of the Listeners with matching Protocol values MUST have different\n                  values for other fields.\n\n                  The set of fields that MUST be different for a Listener differs per protocol.\n                  The following rules define the rules for what fields MUST be considered for\n                  Listeners to be distinct with each protocol currently defined in the\n                  Gateway API spec.\n\n                  The set of listeners that all share a protocol value MUST have _different_\n                  values for _at least one_ of these fields to be distinct:\n\n                  * **HTTP, HTTPS, TLS**: Port, Hostname\n                  * **TCP, UDP**: Port\n\n                  One **very** important rule to call out involves what happens when an\n                  implementation:\n\n                  * Supports TCP protocol Listeners, as well as HTTP, HTTPS, or TLS protocol\n                    Listeners, and\n                  * sees HTTP, HTTPS, or TLS protocols with the same `port` as one with TCP\n                    Protocol.\n\n                  In this case all the Listeners that share a port with the\n                  TCP Listener are not distinct and so MUST NOT be accepted.\n\n                  If an implementation does not support TCP Protocol Listeners, then the\n                  previous rule does not apply, and the TCP Listeners SHOULD NOT be\n                  accepted.\n\n                  Note that the `tls` field is not used for determining if a listener is distinct, because\n                  Listeners that _only_ differ on TLS config will still conflict in all cases.\n\n                  ### Listeners that are distinct only by Hostname\n\n                  When the Listeners are distinct based only on Hostname, inbound request\n                  hostnames MUST match from the most specific to least specific Hostname\n                  values to choose the correct Listener and its associated set of Routes.\n\n                  Exact matches MUST be processed before wildcard matches, and wildcard\n                  matches MUST be processed before fallback (empty Hostname value)\n                  matches. For example, `\"foo.example.com\"` takes precedence over\n                  `\"*.example.com\"`, and `\"*.example.com\"` takes precedence over `\"\"`.\n\n                  Additionally, if there are multiple wildcard entries, more specific\n                  wildcard entries must be processed before less specific wildcard entries.\n                  For example, `\"*.foo.example.com\"` takes precedence over `\"*.example.com\"`.\n\n                  The precise definition here is that the higher the number of dots in the\n                  hostname to the right of the wildcard character, the higher the precedence.\n\n                  The wildcard character will match any number of characters _and dots_ to\n                  the left, however, so `\"*.example.com\"` will match both\n                  `\"foo.bar.example.com\"` _and_ `\"bar.example.com\"`.\n\n                  ## Handling indistinct Listeners\n\n                  If a set of Listeners contains Listeners that are not distinct, then those\n                  Listeners are _Conflicted_, and the implementation MUST set the \"Conflicted\"\n                  condition in the Listener Status to \"True\".\n\n                  The words \"indistinct\" and \"conflicted\" are considered equivalent for the\n                  purpose of this documentation.\n\n                  Implementations MAY choose to accept a Gateway with some Conflicted\n                  Listeners only if they only accept the partial Listener set that contains\n                  no Conflicted Listeners.\n\n                  Specifically, an implementation MAY accept a partial Listener set subject to\n                  the following rules:\n\n                  * The implementation MUST NOT pick one conflicting Listener as the winner.\n                    ALL indistinct Listeners must not be accepted for processing.\n                  * At least one distinct Listener MUST be present, or else the Gateway effectively\n                    contains _no_ Listeners, and must be rejected from processing as a whole.\n\n                  The implementation MUST set a \"ListenersNotValid\" condition on the\n                  Gateway Status when the Gateway contains Conflicted Listeners whether or\n                  not they accept the Gateway. That Condition SHOULD clearly\n                  indicate in the Message which Listeners are conflicted, and which are\n                  Accepted. Additionally, the Listener status for those listeners SHOULD\n                  indicate which Listeners are conflicted and not Accepted.\n\n                  ## General Listener behavior\n\n                  Note that, for all distinct Listeners, requests SHOULD match at most one Listener.\n                  For example, if Listeners are defined for \"foo.example.com\" and \"*.example.com\", a\n                  request to \"foo.example.com\" SHOULD only be routed using routes attached\n                  to the \"foo.example.com\" Listener (and not the \"*.example.com\" Listener).\n\n                  This concept is known as \"Listener Isolation\", and it is an Extended feature\n                  of Gateway API. Implementations that do not support Listener Isolation MUST\n                  clearly document this, and MUST NOT claim support for the\n                  `GatewayHTTPListenerIsolation` feature.\n\n                  Implementations that _do_ support Listener Isolation SHOULD claim support\n                  for the Extended `GatewayHTTPListenerIsolation` feature and pass the associated\n                  conformance tests.\n\n                  ## Compatible Listeners\n\n                  A Gateway's Listeners are considered _compatible_ if:\n\n                  1. They are distinct.\n                  2. The implementation can serve them in compliance with the Addresses\n                     requirement that all Listeners are available on all assigned\n                     addresses.\n\n                  Compatible combinations in Extended support are expected to vary across\n                  implementations. A combination that is compatible for one implementation\n                  may not be compatible for another.\n\n                  For example, an implementation that cannot serve both TCP and UDP listeners\n                  on the same address, or cannot mix HTTPS and generic TLS listens on the same port\n                  would not consider those cases compatible, even though they are distinct.\n\n                  Implementations MAY merge separate Gateways onto a single set of\n                  Addresses if all Listeners across all Gateways are compatible.\n\n                  In a future release the MinItems=1 requirement MAY be dropped.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Listener embodies the concept of a logical endpoint where a Gateway accepts\n                    network connections.\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n\n                        Support: Core\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match both the SNI and Host header.\n                          Note that this does not require the SNI and Host header to be the same.\n                          The semantics of this are described in more detail below.\n\n                        To ensure security, Section 11.1 of RFC-6066 emphasizes that server\n                        implementations that rely on SNI hostname matching MUST also verify\n                        hostnames within the application protocol.\n\n                        Section 9.1.2 of RFC-7540 provides a mechanism for servers to reject the\n                        reuse of a connection by responding with the HTTP 421 Misdirected Request\n                        status code. This indicates that the origin server has rejected the\n                        request because it appears to have been misdirected.\n\n                        To detect misdirected requests, Gateways SHOULD match the authority of\n                        the requests with all the SNI hostname(s) configured across all the\n                        Gateway Listeners on the same port and protocol:\n\n                        * If another Listener has an exact match or more specific wildcard entry,\n                          the Gateway SHOULD return a 421.\n                        * If the current Listener (selected by SNI matching during ClientHello)\n                          does not match the Host:\n                            * If another Listener does match the Host, the Gateway SHOULD return a\n                              421.\n                            * If no other Listener matches the Host, the Gateway MUST return a\n                              404.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n\n                        Support: Core\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    protocol:\n                      description: |-\n                        Protocol specifies the network protocol this listener expects to receive.\n\n                        Support: Core\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n\n                        Support: Core\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - port\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: tls mode must be set for protocol TLS\n                  rule: 'self.all(l, (l.protocol == ''TLS'' ? has(l.tls) && has(l.tls.mode)\n                    && l.tls.mode != '''' : true))'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol\n                    == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname\n                    == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'\n              tls:\n                description: |-\n                  TLS specifies frontend and backend tls configuration for entire gateway.\n\n                  Support: Extended\n                properties:\n                  backend:\n                    description: |-\n                      Backend describes TLS configuration for gateway when connecting\n                      to backends.\n\n                      Note that this contains only details for the Gateway as a TLS client,\n                      and does _not_ imply behavior about how to choose which backend should\n                      get a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\n                      Support: Core\n                    properties:\n                      clientCertificateRef:\n                        description: |-\n                          ClientCertificateRef references an object that contains a client certificate\n                          and its associated private key. It can reference standard Kubernetes resources,\n                          i.e., Secret, or implementation-specific custom resources.\n\n                          A ClientCertificateRef is considered invalid if:\n\n                          * It refers to a resource that cannot be resolved (e.g., the referenced resource\n                            does not exist) or is misconfigured (e.g., a Secret does not contain the keys\n                            named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef`\n                            and the Message of the Condition MUST indicate why the reference is invalid.\n\n                          * It refers to a resource in another namespace UNLESS there is a ReferenceGrant\n                            in the target namespace that allows the certificate to be attached.\n                            If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition\n                            on the Gateway MUST be set to False with the Reason `RefNotPermitted`.\n\n                          Implementations MAY choose to perform further validation of the certificate\n                          content (e.g., checking expiry or enforcing specific formats). In such cases,\n                          an implementation-specific Reason and Message MUST be set.\n\n                          Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`).\n                          Support: Implementation-specific - Other resource kinds or Secrets with a\n                          different type (e.g., `Opaque`).\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Secret\n                            description: Kind is kind of the referent. For example\n                              \"Secret\".\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the referenced object. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                        required:\n                        - name\n                        type: object\n                    type: object\n                  frontend:\n                    description: |-\n                      Frontend describes TLS config when client connects to Gateway.\n                      Support: Core\n                    properties:\n                      default:\n                        description: |-\n                          Default specifies the default client certificate validation configuration\n                          for all Listeners handling HTTPS traffic, unless a per-port configuration\n                          is defined.\n\n                          support: Core\n                        properties:\n                          validation:\n                            description: |-\n                              Validation holds configuration information for validating the frontend (client).\n                              Setting this field will result in mutual authentication when connecting to the gateway.\n                              In browsers this may result in a dialog appearing\n                              that requests a user to specify the client certificate.\n                              The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                              Support: Core\n                            properties:\n                              caCertificateRefs:\n                                description: |-\n                                  CACertificateRefs contains one or more references to Kubernetes\n                                  objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                  is used as a trust anchor to validate the certificates presented by\n                                  the client.\n\n                                  A CACertificateRef is invalid if:\n\n                                  * It refers to a resource that cannot be resolved (e.g., the\n                                    referenced resource does not exist) or is misconfigured (e.g., a\n                                    ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                    Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                    and the Message of the Condition must indicate which reference is invalid and why.\n\n                                  * It refers to an unknown or unsupported kind of resource. In this\n                                    case, the Reason on all matching HTTPS listeners must be set to\n                                    `InvalidCACertificateKind` and the Message of the Condition must explain\n                                    which kind of resource is unknown or unsupported.\n\n                                  * It refers to a resource in another namespace UNLESS there is a\n                                    ReferenceGrant in the target namespace that allows the CA\n                                    certificate to be attached. If a ReferenceGrant does not allow this\n                                    reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                    MUST be set with the Reason `RefNotPermitted`.\n\n                                  Implementations MAY choose to perform further validation of the\n                                  certificate content (e.g., checking expiry or enforcing specific formats).\n                                  In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                  In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                  condition is set to `status: False` on all targeted listeners (i.e.,\n                                  listeners serving HTTPS on a matching port). The condition MUST\n                                  include a Reason and Message that indicate the cause of the error. If\n                                  ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                  the `Accepted` condition on the listener is set to `status: False`, with\n                                  the Reason `NoValidCACertificate`.\n                                  Implementations MAY choose to support attaching multiple CA certificates\n                                  to a listener, but this behavior is implementation-specific.\n\n                                  Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                  CA certificate in a key named `ca.crt`.\n\n                                  Support: Implementation-specific - More than one reference, other kinds\n                                  of resources, or a single reference that includes multiple certificates.\n                                items:\n                                  description: |-\n                                    ObjectReference identifies an API object including its namespace.\n\n                                    The API object must be valid in the cluster; the Group and Kind must\n                                    be registered in the cluster for this reference to be valid.\n\n                                    References to objects with invalid Group and Kind are not valid, and must\n                                    be rejected by the implementation, with appropriate Conditions set\n                                    on the containing object.\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When set to the empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"ConfigMap\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of the referenced object. When unspecified, the local\n                                        namespace is inferred.\n\n                                        Note that when a namespace different than the local namespace is specified,\n                                        a ReferenceGrant object is required in the referent namespace to allow that\n                                        namespace's owner to accept the reference. See the ReferenceGrant\n                                        documentation for details.\n\n                                        Support: Core\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                maxItems: 8\n                                minItems: 1\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              mode:\n                                default: AllowValidOnly\n                                description: |-\n                                  FrontendValidationMode defines the mode for validating the client certificate.\n                                  There are two possible modes:\n\n                                  - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                    the client presents a valid certificate. This certificate must successfully\n                                    pass validation against the CA certificates specified in `CACertificateRefs`.\n                                  - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                    even if the client certificate is not presented or fails verification.\n\n                                    This approach delegates client authorization to the backend and introduce\n                                    a significant security risk. It should be used in testing environments or\n                                    on a temporary basis in non-testing environments.\n\n                                  Defaults to AllowValidOnly.\n\n                                  Support: Core\n                                enum:\n                                - AllowValidOnly\n                                - AllowInsecureFallback\n                                type: string\n                            required:\n                            - caCertificateRefs\n                            type: object\n                        type: object\n                      perPort:\n                        description: |-\n                          PerPort specifies tls configuration assigned per port.\n                          Per port configuration is optional. Once set this configuration overrides\n                          the default configuration for all Listeners handling HTTPS traffic\n                          that match this port.\n                          Each override port requires a unique TLS configuration.\n\n                          support: Core\n                        items:\n                          properties:\n                            port:\n                              description: |-\n                                The Port indicates the Port Number to which the TLS configuration will be\n                                applied. This configuration will be applied to all Listeners handling HTTPS\n                                traffic that match this port.\n\n                                Support: Core\n                              format: int32\n                              maximum: 65535\n                              minimum: 1\n                              type: integer\n                            tls:\n                              description: |-\n                                TLS store the configuration that will be applied to all Listeners handling\n                                HTTPS traffic and matching given port.\n\n                                Support: Core\n                              properties:\n                                validation:\n                                  description: |-\n                                    Validation holds configuration information for validating the frontend (client).\n                                    Setting this field will result in mutual authentication when connecting to the gateway.\n                                    In browsers this may result in a dialog appearing\n                                    that requests a user to specify the client certificate.\n                                    The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\n                                    Support: Core\n                                  properties:\n                                    caCertificateRefs:\n                                      description: |-\n                                        CACertificateRefs contains one or more references to Kubernetes\n                                        objects that contain a PEM-encoded TLS CA certificate bundle, which\n                                        is used as a trust anchor to validate the certificates presented by\n                                        the client.\n\n                                        A CACertificateRef is invalid if:\n\n                                        * It refers to a resource that cannot be resolved (e.g., the\n                                          referenced resource does not exist) or is misconfigured (e.g., a\n                                          ConfigMap does not contain a key named `ca.crt`). In this case, the\n                                          Reason on all matching HTTPS listeners must be set to `InvalidCACertificateRef`\n                                          and the Message of the Condition must indicate which reference is invalid and why.\n\n                                        * It refers to an unknown or unsupported kind of resource. In this\n                                          case, the Reason on all matching HTTPS listeners must be set to\n                                          `InvalidCACertificateKind` and the Message of the Condition must explain\n                                          which kind of resource is unknown or unsupported.\n\n                                        * It refers to a resource in another namespace UNLESS there is a\n                                          ReferenceGrant in the target namespace that allows the CA\n                                          certificate to be attached. If a ReferenceGrant does not allow this\n                                          reference, the `ResolvedRefs` on all matching HTTPS listeners condition\n                                          MUST be set with the Reason `RefNotPermitted`.\n\n                                        Implementations MAY choose to perform further validation of the\n                                        certificate content (e.g., checking expiry or enforcing specific formats).\n                                        In such cases, an implementation-specific Reason and Message MUST be set.\n\n                                        In all cases, the implementation MUST ensure that the `ResolvedRefs`\n                                        condition is set to `status: False` on all targeted listeners (i.e.,\n                                        listeners serving HTTPS on a matching port). The condition MUST\n                                        include a Reason and Message that indicate the cause of the error. If\n                                        ALL CACertificateRefs are invalid, the implementation MUST also ensure\n                                        the `Accepted` condition on the listener is set to `status: False`, with\n                                        the Reason `NoValidCACertificate`.\n                                        Implementations MAY choose to support attaching multiple CA certificates\n                                        to a listener, but this behavior is implementation-specific.\n\n                                        Support: Core - A single reference to a Kubernetes ConfigMap, with the\n                                        CA certificate in a key named `ca.crt`.\n\n                                        Support: Implementation-specific - More than one reference, other kinds\n                                        of resources, or a single reference that includes multiple certificates.\n                                      items:\n                                        description: |-\n                                          ObjectReference identifies an API object including its namespace.\n\n                                          The API object must be valid in the cluster; the Group and Kind must\n                                          be registered in the cluster for this reference to be valid.\n\n                                          References to objects with invalid Group and Kind are not valid, and must\n                                          be rejected by the implementation, with appropriate Conditions set\n                                          on the containing object.\n                                        properties:\n                                          group:\n                                            description: |-\n                                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                              When set to the empty string, core API group is inferred.\n                                            maxLength: 253\n                                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                            type: string\n                                          kind:\n                                            description: Kind is kind of the referent.\n                                              For example \"ConfigMap\" or \"Service\".\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                            type: string\n                                          name:\n                                            description: Name is the name of the referent.\n                                            maxLength: 253\n                                            minLength: 1\n                                            type: string\n                                          namespace:\n                                            description: |-\n                                              Namespace is the namespace of the referenced object. When unspecified, the local\n                                              namespace is inferred.\n\n                                              Note that when a namespace different than the local namespace is specified,\n                                              a ReferenceGrant object is required in the referent namespace to allow that\n                                              namespace's owner to accept the reference. See the ReferenceGrant\n                                              documentation for details.\n\n                                              Support: Core\n                                            maxLength: 63\n                                            minLength: 1\n                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                            type: string\n                                        required:\n                                        - group\n                                        - kind\n                                        - name\n                                        type: object\n                                      maxItems: 8\n                                      minItems: 1\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    mode:\n                                      default: AllowValidOnly\n                                      description: |-\n                                        FrontendValidationMode defines the mode for validating the client certificate.\n                                        There are two possible modes:\n\n                                        - AllowValidOnly: In this mode, the gateway will accept connections only if\n                                          the client presents a valid certificate. This certificate must successfully\n                                          pass validation against the CA certificates specified in `CACertificateRefs`.\n                                        - AllowInsecureFallback: In this mode, the gateway will accept connections\n                                          even if the client certificate is not presented or fails verification.\n\n                                          This approach delegates client authorization to the backend and introduce\n                                          a significant security risk. It should be used in testing environments or\n                                          on a temporary basis in non-testing environments.\n\n                                        Defaults to AllowValidOnly.\n\n                                        Support: Core\n                                      enum:\n                                      - AllowValidOnly\n                                      - AllowInsecureFallback\n                                      type: string\n                                  required:\n                                  - caCertificateRefs\n                                  type: object\n                              type: object\n                          required:\n                          - port\n                          - tls\n                          type: object\n                        maxItems: 64\n                        type: array\n                        x-kubernetes-list-map-keys:\n                        - port\n                        x-kubernetes-list-type: map\n                        x-kubernetes-validations:\n                        - message: Port for TLS configuration must be unique within\n                            the Gateway\n                          rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))\n                    required:\n                    - default\n                    type: object\n                type: object\n            required:\n            - gatewayClassName\n            - listeners\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of Gateway.\n            properties:\n              addresses:\n                description: |-\n                  Addresses lists the network addresses that have been bound to the\n                  Gateway.\n\n                  This list may differ from the addresses provided in the spec under some\n                  conditions:\n\n                    * no addresses are specified, all addresses are dynamically assigned\n                    * a combination of specified and dynamic addresses are assigned\n                    * a specified address was unusable (e.g. already in use)\n                items:\n                  description: GatewayStatusAddress describes a network address that\n                    is bound to a Gateway.\n                  oneOf:\n                  - properties:\n                      type:\n                        enum:\n                        - IPAddress\n                      value:\n                        anyOf:\n                        - format: ipv4\n                        - format: ipv6\n                  - properties:\n                      type:\n                        not:\n                          enum:\n                          - IPAddress\n                  properties:\n                    type:\n                      default: IPAddress\n                      description: Type of the address.\n                      maxLength: 253\n                      minLength: 1\n                      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\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    value:\n                      description: |-\n                        Value of the address. The validity of the values will depend\n                        on the type and support by the controller.\n\n                        Examples: `1.2.3.4`, `128::1`, `my-ip-address`.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - value\n                  type: object\n                  x-kubernetes-validations:\n                  - message: Hostname value must only contain valid characters (matching\n                      ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)\n                    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])?)*$\"\"\"):\n                      true'\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              attachedListenerSets:\n                description: |-\n                  AttachedListenerSets represents the total number of ListenerSets that have been\n                  successfully attached to this Gateway.\n\n                  A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n                  - The ListenerSet is selected by the Gateway's AllowedListeners field\n                  - The ListenerSet has a valid ParentRef selecting the Gateway\n                  - The ListenerSet's status has the condition \"Accepted: true\"\n\n                  Uses for this field include troubleshooting AttachedListenerSets attachment and\n                  measuring blast radius/impact of changes to a Gateway.\n                format: int32\n                type: integer\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the Gateway.\n\n                  Implementations should prefer to express Gateway conditions\n                  using the `GatewayConditionType` and `GatewayConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe Gateway state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                  * \"Ready\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener or Route status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners, even if the Accepted condition of an individual Listener is set\n                        to \"False\". The AttachedRoutes number represents the number of Routes with\n                        the Accepted condition set to \"True\" that have been attached to this Listener.\n                        Routes with any other value for the Accepted condition MUST NOT be included\n                        in this count.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds supported by an implementation for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_grpcroutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: grpcroutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: GRPCRoute\n    listKind: GRPCRouteList\n    plural: grpcroutes\n    singular: grpcroute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.hostnames\n      name: Hostnames\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          GRPCRoute provides a way to route gRPC requests. This includes the capability\n          to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header.\n          Filters can be used to specify additional processing steps. Backends specify\n          where matching requests will be routed.\n\n          GRPCRoute falls under extended support within the Gateway API. Within the\n          following specification, the word \"MUST\" indicates that an implementation\n          supporting GRPCRoute must conform to the indicated requirement, but an\n          implementation not supporting this route type need not follow the requirement\n          unless explicitly indicated.\n\n          Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST\n          accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via\n          ALPN. If the implementation does not support this, then it MUST set the\n          \"Accepted\" condition to \"False\" for the affected listener with a reason of\n          \"UnsupportedProtocol\".  Implementations MAY also accept HTTP/2 connections\n          with an upgrade from HTTP/1.\n\n          Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST\n          support HTTP/2 over cleartext TCP (h2c,\n          https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial\n          upgrade from HTTP/1.1, i.e. with prior knowledge\n          (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation\n          does not support this, then it MUST set the \"Accepted\" condition to \"False\"\n          for the affected listener with a reason of \"UnsupportedProtocol\".\n          Implementations MAY also accept HTTP/2 connections with an upgrade from\n          HTTP/1, i.e. without prior knowledge.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of GRPCRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of hostnames to match against the GRPC\n                  Host header to select a GRPCRoute to process the request. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label MUST appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and GRPCRoute, there\n                  MUST be at least one intersecting hostname for the GRPCRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches GRPCRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches GRPCRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `test.example.com` and `*.example.com` would both match. On the other\n                    hand, `example.com` and `test.example.net` would not match.\n\n                  Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                  as a suffix match. That means that a match for `*.example.com` would match\n                  both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                  If both the Listener and GRPCRoute have specified hostnames, any\n                  GRPCRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  GRPCRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` MUST NOT be considered for a match.\n\n                  If both the Listener and GRPCRoute have specified hostnames, and none\n                  match with the criteria above, then the GRPCRoute MUST NOT be accepted by\n                  the implementation. The implementation MUST raise an 'Accepted' Condition\n                  with a status of `False` in the corresponding RouteParentStatus.\n\n                  If a Route (A) of type HTTPRoute or GRPCRoute is attached to a\n                  Listener and that listener already has another Route (B) of the other\n                  type attached and the intersection of the hostnames of A and B is\n                  non-empty, then the implementation MUST accept exactly one of these two\n                  routes, determined by the following criteria, in order:\n\n                  * The oldest Route based on creation timestamp.\n                  * The Route appearing first in alphabetical order by\n                    \"{namespace}/{name}\".\n\n                  The rejected Route MUST raise an 'Accepted' condition with a status of\n                  'False' in the corresponding RouteParentStatus.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''')) : true))'\n                - message: sectionName must be unique when parentRefs includes 2 or\n                    more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              rules:\n                description: Rules are a list of GRPC matchers, filters and actions.\n                items:\n                  description: |-\n                    GRPCRouteRule defines the semantics for matching a gRPC request based on\n                    conditions (matches), processing it (filters), and forwarding the request to\n                    an API object (backendRefs).\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent.\n\n                        Failure behavior here depends on how many BackendRefs are specified and\n                        how many are invalid.\n\n                        If *all* entries in BackendRefs are invalid, and there are also no filters\n                        specified in this route rule, *all* traffic which matches this rule MUST\n                        receive an `UNAVAILABLE` status.\n\n                        See the GRPCBackendRef definition for the rules about what makes a single\n                        GRPCBackendRef invalid.\n\n                        When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for\n                        requests that would have otherwise been routed to an invalid backend. If\n                        multiple backends are specified, and some are invalid, the proportion of\n                        requests that would otherwise have been routed to an invalid backend\n                        MUST receive an `UNAVAILABLE` status.\n\n                        For example, if two backends are specified with equal weights, and one is\n                        invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status.\n                        Implementations may choose how that 50 percent is determined.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Core\n                      items:\n                        description: |-\n                          GRPCBackendRef defines how a GRPCRoute forwards a gRPC request.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n                        properties:\n                          filters:\n                            description: |-\n                              Filters defined at this level MUST be executed if and only if the\n                              request is being forwarded to the backend defined here.\n\n                              Support: Implementation-specific (For broader support of filters, use the\n                              Filters field in GRPCRouteRule.)\n                            items:\n                              description: |-\n                                GRPCRouteFilter defines processing steps that must be completed during the\n                                request or response lifecycle. GRPCRouteFilters are meant as an extension\n                                point to express processing that may be done in Gateway implementations. Some\n                                examples include request or response modification, implementing\n                                authentication strategies, rate-limiting, and traffic shaping. API\n                                guarantee/conformance is defined based on the type of the filter.\n                              properties:\n                                extensionRef:\n                                  description: |-\n                                    ExtensionRef is an optional, implementation-specific extension to the\n                                    \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                                    \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                                    extended filters.\n\n                                    Support: Implementation-specific\n\n                                    This filter can be used multiple times within the same rule.\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When unspecified or empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"HTTPRoute\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                requestHeaderModifier:\n                                  description: |-\n                                    RequestHeaderModifier defines a schema for a filter that modifies request\n                                    headers.\n\n                                    Support: Core\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                requestMirror:\n                                  description: |-\n                                    RequestMirror defines a schema for a filter that mirrors requests.\n                                    Requests are sent to the specified destination, but responses from\n                                    that destination are ignored.\n\n                                    This filter can be used multiple times within the same rule. Note that\n                                    not all implementations will be able to support mirroring to multiple\n                                    backends.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef references a resource where mirrored requests are sent.\n\n                                        Mirrored requests must be sent only to a single destination endpoint\n                                        within this BackendRef, irrespective of how many endpoints are present\n                                        within this BackendRef.\n\n                                        If the referent cannot be found, this BackendRef is invalid and must be\n                                        dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                        condition on the Route status is set to `status: False` and not configure\n                                        this backend in the underlying implementation.\n\n                                        If there is a cross-namespace reference to an *existing* object\n                                        that is not allowed by a ReferenceGrant, the controller must ensure the\n                                        \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                        with the \"RefNotPermitted\" reason and not configure this backend in the\n                                        underlying implementation.\n\n                                        In either error case, the Message of the `ResolvedRefs` Condition\n                                        should be used to provide more detail about the problem.\n\n                                        Support: Extended for Kubernetes Service\n\n                                        Support: Implementation-specific for any other resource\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    fraction:\n                                      description: |-\n                                        Fraction represents the fraction of requests that should be\n                                        mirrored to BackendRef.\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      properties:\n                                        denominator:\n                                          default: 100\n                                          format: int32\n                                          minimum: 1\n                                          type: integer\n                                        numerator:\n                                          format: int32\n                                          minimum: 0\n                                          type: integer\n                                      required:\n                                      - numerator\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: numerator must be less than or equal\n                                          to denominator\n                                        rule: self.numerator <= self.denominator\n                                    percent:\n                                      description: |-\n                                        Percent represents the percentage of requests that should be\n                                        mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                        requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      format: int32\n                                      maximum: 100\n                                      minimum: 0\n                                      type: integer\n                                  required:\n                                  - backendRef\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: Only one of percent or fraction may be\n                                      specified in HTTPRequestMirrorFilter\n                                    rule: '!(has(self.percent) && has(self.fraction))'\n                                responseHeaderModifier:\n                                  description: |-\n                                    ResponseHeaderModifier defines a schema for a filter that modifies response\n                                    headers.\n\n                                    Support: Extended\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                type:\n                                  description: |-\n                                    Type identifies the type of filter to apply. As with other API fields,\n                                    types are classified into three conformance levels:\n\n                                    - Core: Filter types and their corresponding configuration defined by\n                                      \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                      implementations supporting GRPCRoute MUST support core filters.\n\n                                    - Extended: Filter types and their corresponding configuration defined by\n                                      \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                      are encouraged to support extended filters.\n\n                                    - Implementation-specific: Filters that are defined and supported by specific vendors.\n                                      In the future, filters showing convergence in behavior across multiple\n                                      implementations will be considered for inclusion in extended or core\n                                      conformance levels. Filter-specific configuration for such filters\n                                      is specified using the ExtensionRef field. `Type` MUST be set to\n                                      \"ExtensionRef\" for custom filters.\n\n                                    Implementers are encouraged to define custom implementation types to\n                                    extend the core API with implementation-specific behavior.\n\n                                    If a reference to a custom filter type cannot be resolved, the filter\n                                    MUST NOT be skipped. Instead, requests that would have been processed by\n                                    that filter MUST receive a HTTP error response.\n                                  enum:\n                                  - ResponseHeaderModifier\n                                  - RequestHeaderModifier\n                                  - RequestMirror\n                                  - ExtensionRef\n                                  type: string\n                              required:\n                              - type\n                              type: object\n                              x-kubernetes-validations:\n                              - message: filter.requestHeaderModifier must be nil\n                                  if the filter.type is not RequestHeaderModifier\n                                rule: '!(has(self.requestHeaderModifier) && self.type\n                                  != ''RequestHeaderModifier'')'\n                              - message: filter.requestHeaderModifier must be specified\n                                  for RequestHeaderModifier filter.type\n                                rule: '!(!has(self.requestHeaderModifier) && self.type\n                                  == ''RequestHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be nil\n                                  if the filter.type is not ResponseHeaderModifier\n                                rule: '!(has(self.responseHeaderModifier) && self.type\n                                  != ''ResponseHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be specified\n                                  for ResponseHeaderModifier filter.type\n                                rule: '!(!has(self.responseHeaderModifier) && self.type\n                                  == ''ResponseHeaderModifier'')'\n                              - message: filter.requestMirror must be nil if the filter.type\n                                  is not RequestMirror\n                                rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                              - message: filter.requestMirror must be specified for\n                                  RequestMirror filter.type\n                                rule: '!(!has(self.requestMirror) && self.type ==\n                                  ''RequestMirror'')'\n                              - message: filter.extensionRef must be nil if the filter.type\n                                  is not ExtensionRef\n                                rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                              - message: filter.extensionRef must be specified for\n                                  ExtensionRef filter.type\n                                rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-type: atomic\n                            x-kubernetes-validations:\n                            - message: RequestHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                                <= 1\n                            - message: ResponseHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                                <= 1\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    filters:\n                      description: |-\n                        Filters define the filters that are applied to requests that match\n                        this rule.\n\n                        The effects of ordering of multiple behaviors are currently unspecified.\n                        This can change in the future based on feedback during the alpha stage.\n\n                        Conformance-levels at this level are defined based on the type of filter:\n\n                        - ALL core filters MUST be supported by all implementations that support\n                          GRPCRoute.\n                        - Implementers are encouraged to support extended filters.\n                        - Implementation-specific custom filters have no API guarantees across\n                          implementations.\n\n                        Specifying the same filter multiple times is not supported unless explicitly\n                        indicated in the filter.\n\n                        If an implementation cannot support a combination of filters, it must clearly\n                        document that limitation. In cases where incompatible or unsupported\n                        filters are specified and cause the `Accepted` condition to be set to status\n                        `False`, implementations may use the `IncompatibleFilters` reason to specify\n                        this configuration error.\n\n                        Support: Core\n                      items:\n                        description: |-\n                          GRPCRouteFilter defines processing steps that must be completed during the\n                          request or response lifecycle. GRPCRouteFilters are meant as an extension\n                          point to express processing that may be done in Gateway implementations. Some\n                          examples include request or response modification, implementing\n                          authentication strategies, rate-limiting, and traffic shaping. API\n                          guarantee/conformance is defined based on the type of the filter.\n                        properties:\n                          extensionRef:\n                            description: |-\n                              ExtensionRef is an optional, implementation-specific extension to the\n                              \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                              \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                              extended filters.\n\n                              Support: Implementation-specific\n\n                              This filter can be used multiple times within the same rule.\n                            properties:\n                              group:\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is kind of the referent. For example\n                                  \"HTTPRoute\" or \"Service\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                            required:\n                            - group\n                            - kind\n                            - name\n                            type: object\n                          requestHeaderModifier:\n                            description: |-\n                              RequestHeaderModifier defines a schema for a filter that modifies request\n                              headers.\n\n                              Support: Core\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          requestMirror:\n                            description: |-\n                              RequestMirror defines a schema for a filter that mirrors requests.\n                              Requests are sent to the specified destination, but responses from\n                              that destination are ignored.\n\n                              This filter can be used multiple times within the same rule. Note that\n                              not all implementations will be able to support mirroring to multiple\n                              backends.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef references a resource where mirrored requests are sent.\n\n                                  Mirrored requests must be sent only to a single destination endpoint\n                                  within this BackendRef, irrespective of how many endpoints are present\n                                  within this BackendRef.\n\n                                  If the referent cannot be found, this BackendRef is invalid and must be\n                                  dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                  condition on the Route status is set to `status: False` and not configure\n                                  this backend in the underlying implementation.\n\n                                  If there is a cross-namespace reference to an *existing* object\n                                  that is not allowed by a ReferenceGrant, the controller must ensure the\n                                  \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                  with the \"RefNotPermitted\" reason and not configure this backend in the\n                                  underlying implementation.\n\n                                  In either error case, the Message of the `ResolvedRefs` Condition\n                                  should be used to provide more detail about the problem.\n\n                                  Support: Extended for Kubernetes Service\n\n                                  Support: Implementation-specific for any other resource\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              fraction:\n                                description: |-\n                                  Fraction represents the fraction of requests that should be\n                                  mirrored to BackendRef.\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                properties:\n                                  denominator:\n                                    default: 100\n                                    format: int32\n                                    minimum: 1\n                                    type: integer\n                                  numerator:\n                                    format: int32\n                                    minimum: 0\n                                    type: integer\n                                required:\n                                - numerator\n                                type: object\n                                x-kubernetes-validations:\n                                - message: numerator must be less than or equal to\n                                    denominator\n                                  rule: self.numerator <= self.denominator\n                              percent:\n                                description: |-\n                                  Percent represents the percentage of requests that should be\n                                  mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                  requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                format: int32\n                                maximum: 100\n                                minimum: 0\n                                type: integer\n                            required:\n                            - backendRef\n                            type: object\n                            x-kubernetes-validations:\n                            - message: Only one of percent or fraction may be specified\n                                in HTTPRequestMirrorFilter\n                              rule: '!(has(self.percent) && has(self.fraction))'\n                          responseHeaderModifier:\n                            description: |-\n                              ResponseHeaderModifier defines a schema for a filter that modifies response\n                              headers.\n\n                              Support: Extended\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          type:\n                            description: |-\n                              Type identifies the type of filter to apply. As with other API fields,\n                              types are classified into three conformance levels:\n\n                              - Core: Filter types and their corresponding configuration defined by\n                                \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                implementations supporting GRPCRoute MUST support core filters.\n\n                              - Extended: Filter types and their corresponding configuration defined by\n                                \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                are encouraged to support extended filters.\n\n                              - Implementation-specific: Filters that are defined and supported by specific vendors.\n                                In the future, filters showing convergence in behavior across multiple\n                                implementations will be considered for inclusion in extended or core\n                                conformance levels. Filter-specific configuration for such filters\n                                is specified using the ExtensionRef field. `Type` MUST be set to\n                                \"ExtensionRef\" for custom filters.\n\n                              Implementers are encouraged to define custom implementation types to\n                              extend the core API with implementation-specific behavior.\n\n                              If a reference to a custom filter type cannot be resolved, the filter\n                              MUST NOT be skipped. Instead, requests that would have been processed by\n                              that filter MUST receive a HTTP error response.\n                            enum:\n                            - ResponseHeaderModifier\n                            - RequestHeaderModifier\n                            - RequestMirror\n                            - ExtensionRef\n                            type: string\n                        required:\n                        - type\n                        type: object\n                        x-kubernetes-validations:\n                        - message: filter.requestHeaderModifier must be nil if the\n                            filter.type is not RequestHeaderModifier\n                          rule: '!(has(self.requestHeaderModifier) && self.type !=\n                            ''RequestHeaderModifier'')'\n                        - message: filter.requestHeaderModifier must be specified\n                            for RequestHeaderModifier filter.type\n                          rule: '!(!has(self.requestHeaderModifier) && self.type ==\n                            ''RequestHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be nil if the\n                            filter.type is not ResponseHeaderModifier\n                          rule: '!(has(self.responseHeaderModifier) && self.type !=\n                            ''ResponseHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be specified\n                            for ResponseHeaderModifier filter.type\n                          rule: '!(!has(self.responseHeaderModifier) && self.type\n                            == ''ResponseHeaderModifier'')'\n                        - message: filter.requestMirror must be nil if the filter.type\n                            is not RequestMirror\n                          rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                        - message: filter.requestMirror must be specified for RequestMirror\n                            filter.type\n                          rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'\n                        - message: filter.extensionRef must be nil if the filter.type\n                            is not ExtensionRef\n                          rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                        - message: filter.extensionRef must be specified for ExtensionRef\n                            filter.type\n                          rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                      x-kubernetes-validations:\n                      - message: RequestHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                          <= 1\n                      - message: ResponseHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                          <= 1\n                    matches:\n                      description: |-\n                        Matches define conditions used for matching the rule against incoming\n                        gRPC requests. Each match is independent, i.e. this rule will be matched\n                        if **any** one of the matches is satisfied.\n\n                        For example, take the following matches configuration:\n\n                        ```\n                        matches:\n                        - method:\n                            service: foo.bar\n                          headers:\n                            values:\n                              version: 2\n                        - method:\n                            service: foo.bar.v2\n                        ```\n\n                        For a request to match against this rule, it MUST satisfy\n                        EITHER of the two conditions:\n\n                        - service of foo.bar AND contains the header `version: 2`\n                        - service of foo.bar.v2\n\n                        See the documentation for GRPCRouteMatch on how to specify multiple\n                        match conditions to be ANDed together.\n\n                        If no matches are specified, the implementation MUST match every gRPC request.\n\n                        Proxy or Load Balancer routing configuration generated from GRPCRoutes\n                        MUST prioritize rules based on the following criteria, continuing on\n                        ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes.\n                        Precedence MUST be given to the rule with the largest number of:\n\n                        * Characters in a matching non-wildcard hostname.\n                        * Characters in a matching hostname.\n                        * Characters in a matching service.\n                        * Characters in a matching method.\n                        * Header matches.\n\n                        If ties still exist across multiple Routes, matching precedence MUST be\n                        determined in order of the following criteria, continuing on ties:\n\n                        * The oldest Route based on creation timestamp.\n                        * The Route appearing first in alphabetical order by\n                          \"{namespace}/{name}\".\n\n                        If ties still exist within the Route that has been given precedence,\n                        matching precedence MUST be granted to the first matching rule meeting\n                        the above criteria.\n                      items:\n                        description: |-\n                          GRPCRouteMatch defines the predicate used to match requests to a given\n                          action. Multiple match types are ANDed together, i.e. the match will\n                          evaluate to true only if all conditions are satisfied.\n\n                          For example, the match below will match a gRPC request only if its service\n                          is `foo` AND it contains the `version: v1` header:\n\n                          ```\n                          matches:\n                            - method:\n                              type: Exact\n                              service: \"foo\"\n                            - headers:\n                              name: \"version\"\n                              value \"v1\"\n\n                          ```\n                        properties:\n                          headers:\n                            description: |-\n                              Headers specifies gRPC request header matchers. Multiple match values are\n                              ANDed together, meaning, a request MUST match all the specified headers\n                              to select the route.\n                            items:\n                              description: |-\n                                GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request\n                                headers.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the gRPC Header to be matched.\n\n                                    If multiple entries specify equivalent header names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent header name MUST be ignored. Due to the\n                                    case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                    equivalent.\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: Type specifies how to match against\n                                    the value of the header.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of the gRPC Header\n                                    to be matched.\n                                  maxLength: 4096\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                          method:\n                            description: |-\n                              Method specifies a gRPC request service/method matcher. If this field is\n                              not specified, all services and methods will match.\n                            properties:\n                              method:\n                                description: |-\n                                  Value of the method to match against. If left empty or omitted, will\n                                  match all services.\n\n                                  At least one of Service and Method MUST be a non-empty string.\n                                maxLength: 1024\n                                type: string\n                              service:\n                                description: |-\n                                  Value of the service to match against. If left empty or omitted, will\n                                  match any service.\n\n                                  At least one of Service and Method MUST be a non-empty string.\n                                maxLength: 1024\n                                type: string\n                              type:\n                                default: Exact\n                                description: |-\n                                  Type specifies how to match against the service and/or method.\n                                  Support: Core (Exact with service and method specified)\n\n                                  Support: Implementation-specific (Exact with method specified but no service specified)\n\n                                  Support: Implementation-specific (RegularExpression)\n                                enum:\n                                - Exact\n                                - RegularExpression\n                                type: string\n                            type: object\n                            x-kubernetes-validations:\n                            - message: One or both of 'service' or 'method' must be\n                                specified\n                              rule: 'has(self.type) ? has(self.service) || has(self.method)\n                                : true'\n                            - message: service must only contain valid characters\n                                (matching ^(?i)\\.?[a-z_][a-z_0-9]*(\\.[a-z_][a-z_0-9]*)*$)\n                              rule: '(!has(self.type) || self.type == ''Exact'') &&\n                                has(self.service) ? self.service.matches(r\"\"\"^(?i)\\.?[a-z_][a-z_0-9]*(\\.[a-z_][a-z_0-9]*)*$\"\"\"):\n                                true'\n                            - message: method must only contain valid characters (matching\n                                ^[A-Za-z_][A-Za-z_0-9]*$)\n                              rule: '(!has(self.type) || self.type == ''Exact'') &&\n                                has(self.method) ? self.method.matches(r\"\"\"^[A-Za-z_][A-Za-z_0-9]*$\"\"\"):\n                                true'\n                        type: object\n                      maxItems: 64\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  type: object\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: While 16 rules and 64 matches per rule are allowed, the\n                    total number of matches across all rules in a route must be less\n                    than 128\n                  rule: '(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size()\n                    : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size()\n                    : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size()\n                    : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size()\n                    : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size()\n                    : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size()\n                    : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size()\n                    : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size()\n                    : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size()\n                    : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size()\n                    : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size()\n                    : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size()\n                    : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size()\n                    : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size()\n                    : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size()\n                    : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size()\n                    : 0) : 0) <= 128'\n            type: object\n          status:\n            description: Status defines the current state of GRPCRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_httproutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: httproutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: HTTPRoute\n    listKind: HTTPRouteList\n    plural: httproutes\n    singular: httproute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.hostnames\n      name: Hostnames\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          HTTPRoute provides a way to route HTTP requests. This includes the capability\n          to match requests by hostname, path, header, or query param. Filters can be\n          used to specify additional processing steps. Backends specify where matching\n          requests should be routed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of HTTPRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of hostnames that should match against the HTTP Host\n                  header to select a HTTPRoute used to process the request. Implementations\n                  MUST ignore any port value specified in the HTTP Host header while\n                  performing a match and (absent of any applicable header modification\n                  configuration) MUST forward this header unmodified to the backend.\n\n                  Valid values for Hostnames are determined by RFC 1123 definition of a\n                  hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and HTTPRoute, there\n                  must be at least one intersecting hostname for the HTTPRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `*.example.com`, `test.example.com`, and `foo.test.example.com` would\n                    all match. On the other hand, `example.com` and `test.example.net` would\n                    not match.\n\n                  Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                  as a suffix match. That means that a match for `*.example.com` would match\n                  both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                  If both the Listener and HTTPRoute have specified hostnames, any\n                  HTTPRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  HTTPRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` must not be considered for a match.\n\n                  If both the Listener and HTTPRoute have specified hostnames, and none\n                  match with the criteria above, then the HTTPRoute is not accepted. The\n                  implementation must raise an 'Accepted' Condition with a status of\n                  `False` in the corresponding RouteParentStatus.\n\n                  In the event that multiple HTTPRoutes specify intersecting hostnames (e.g.\n                  overlapping wildcard matching and exact matching hostnames), precedence must\n                  be given to rules from the HTTPRoute with the largest number of:\n\n                  * Characters in a matching non-wildcard hostname.\n                  * Characters in a matching hostname.\n\n                  If ties exist across multiple Routes, the matching precedence rules for\n                  HTTPRouteMatches takes over.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''')) : true))'\n                - message: sectionName must be unique when parentRefs includes 2 or\n                    more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              rules:\n                default:\n                - matches:\n                  - path:\n                      type: PathPrefix\n                      value: /\n                description: Rules are a list of HTTP matchers, filters and actions.\n                items:\n                  description: |-\n                    HTTPRouteRule defines semantics for matching an HTTP request based on\n                    conditions (matches), processing it (filters), and forwarding the request to\n                    an API object (backendRefs).\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent.\n\n                        Failure behavior here depends on how many BackendRefs are specified and\n                        how many are invalid.\n\n                        If *all* entries in BackendRefs are invalid, and there are also no filters\n                        specified in this route rule, *all* traffic which matches this rule MUST\n                        receive a 500 status code.\n\n                        See the HTTPBackendRef definition for the rules about what makes a single\n                        HTTPBackendRef invalid.\n\n                        When a HTTPBackendRef is invalid, 500 status codes MUST be returned for\n                        requests that would have otherwise been routed to an invalid backend. If\n                        multiple backends are specified, and some are invalid, the proportion of\n                        requests that would otherwise have been routed to an invalid backend\n                        MUST receive a 500 status code.\n\n                        For example, if two backends are specified with equal weights, and one is\n                        invalid, 50 percent of traffic must receive a 500. Implementations may\n                        choose how that 50 percent is determined.\n\n                        When a HTTPBackendRef refers to a Service that has no ready endpoints,\n                        implementations SHOULD return a 503 for requests to that backend instead.\n                        If an implementation chooses to do this, all of the above rules for 500 responses\n                        MUST also apply for responses that return a 503.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Core\n                      items:\n                        description: |-\n                          HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n                        properties:\n                          filters:\n                            description: |-\n                              Filters defined at this level should be executed if and only if the\n                              request is being forwarded to the backend defined here.\n\n                              Support: Implementation-specific (For broader support of filters, use the\n                              Filters field in HTTPRouteRule.)\n                            items:\n                              description: |-\n                                HTTPRouteFilter defines processing steps that must be completed during the\n                                request or response lifecycle. HTTPRouteFilters are meant as an extension\n                                point to express processing that may be done in Gateway implementations. Some\n                                examples include request or response modification, implementing\n                                authentication strategies, rate-limiting, and traffic shaping. API\n                                guarantee/conformance is defined based on the type of the filter.\n                              properties:\n                                cors:\n                                  description: |-\n                                    CORS defines a schema for a filter that responds to the\n                                    cross-origin request based on HTTP response header.\n\n                                    Support: Extended\n                                  properties:\n                                    allowCredentials:\n                                      description: |-\n                                        AllowCredentials indicates whether the actual cross-origin request allows\n                                        to include credentials.\n\n                                        When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                        response header with value true (case-sensitive).\n\n                                        When set to false or omitted the gateway will omit the header\n                                        `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                        behavior).\n\n                                        Support: Extended\n                                      type: boolean\n                                    allowHeaders:\n                                      description: |-\n                                        AllowHeaders indicates which HTTP request headers are supported for\n                                        accessing the requested resource.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        When the `AllowHeaders` field is configured with one or more headers, the\n                                        gateway must return the `Access-Control-Allow-Headers` response header\n                                        which value is present in the `AllowHeaders` field.\n\n                                        If any header name in the `Access-Control-Request-Headers` request header\n                                        is not included in the list of header names specified by the response\n                                        header `Access-Control-Allow-Headers`, it will present an error on the\n                                        client side.\n\n                                        If any header name in the `Access-Control-Allow-Headers` response header\n                                        does not recognize by the client, it will also occur an error on the\n                                        client side.\n\n                                        A wildcard indicates that the requests with all HTTP headers are allowed.\n                                        If config contains the wildcard \"*\" in allowHeaders and the request is\n                                        not credentialed, the `Access-Control-Allow-Headers` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Headers from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Headers` response header. When\n                                        also the `AllowCredentials` field is true and `AllowHeaders` field\n                                        is specified with the `*` wildcard, the gateway must specify one or more\n                                        HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                        header. The value of the header `Access-Control-Allow-Headers` is same as\n                                        the `Access-Control-Request-Headers` header provided by the client. If\n                                        the header `Access-Control-Request-Headers` is not included in the\n                                        request, the gateway will omit the `Access-Control-Allow-Headers`\n                                        response header, instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowHeaders cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowMethods:\n                                      description: |-\n                                        AllowMethods indicates which HTTP methods are supported for accessing the\n                                        requested resource.\n\n                                        Valid values are any method defined by RFC9110, along with the special\n                                        value `*`, which represents all HTTP methods are allowed.\n\n                                        Method names are case-sensitive, so these values are also case-sensitive.\n                                        (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                        Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                        response header are separated by a comma (\",\").\n\n                                        A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                        CORS-safelisted methods are always allowed, regardless of whether they\n                                        are specified in the `AllowMethods` field.\n\n                                        When the `AllowMethods` field is configured with one or more methods, the\n                                        gateway must return the `Access-Control-Allow-Methods` response header\n                                        which value is present in the `AllowMethods` field.\n\n                                        If the HTTP method of the `Access-Control-Request-Method` request header\n                                        is not included in the list of methods specified by the response header\n                                        `Access-Control-Allow-Methods`, it will present an error on the client\n                                        side.\n\n                                        If config contains the wildcard \"*\" in allowMethods and the request is\n                                        not credentialed, the `Access-Control-Allow-Methods` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Method from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Methods` response header. When\n                                        also the `AllowCredentials` field is true and `AllowMethods` field\n                                        specified with the `*` wildcard, the gateway must specify one HTTP method\n                                        in the value of the Access-Control-Allow-Methods response header. The\n                                        value of the header `Access-Control-Allow-Methods` is same as the\n                                        `Access-Control-Request-Method` header provided by the client. If the\n                                        header `Access-Control-Request-Method` is not included in the request,\n                                        the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                        instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        enum:\n                                        - GET\n                                        - HEAD\n                                        - POST\n                                        - PUT\n                                        - DELETE\n                                        - CONNECT\n                                        - OPTIONS\n                                        - TRACE\n                                        - PATCH\n                                        - '*'\n                                        type: string\n                                      maxItems: 9\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowMethods cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowOrigins:\n                                      description: |-\n                                        AllowOrigins indicates whether the response can be shared with requested\n                                        resource from the given `Origin`.\n\n                                        The `Origin` consists of a scheme and a host, with an optional port, and\n                                        takes the form `<scheme>://<host>(:<port>)`.\n\n                                        Valid values for scheme are: `http` and `https`.\n\n                                        Valid values for port are any integer between 1 and 65535 (the list of\n                                        available TCP/UDP ports). Note that, if not included, port `80` is\n                                        assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                        origins. This may affect origin matching.\n\n                                        The host part of the origin may contain the wildcard character `*`. These\n                                        wildcard characters behave as follows:\n\n                                        * `*` is a greedy match to the _left_, including any number of\n                                          DNS labels to the left of its position. This also means that\n                                          `*` will include any number of period `.` characters to the\n                                          left of its position.\n                                        * A wildcard by itself matches all hosts.\n\n                                        An origin value that includes _only_ the `*` character indicates requests\n                                        from all `Origin`s are allowed.\n\n                                        When the `AllowOrigins` field is configured with multiple origins, it\n                                        means the server supports clients from multiple origins. If the request\n                                        `Origin` matches the configured allowed origins, the gateway must return\n                                        the given `Origin` and sets value of the header\n                                        `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                        client.\n\n                                        The status code of a successful response to a \"preflight\" request is\n                                        always an OK status (i.e., 204 or 200).\n\n                                        If the request `Origin` does not match the configured allowed origins,\n                                        the gateway returns 204/200 response but doesn't set the relevant\n                                        cross-origin response headers. Alternatively, the gateway responds with\n                                        403 status to the \"preflight\" request is denied, coupled with omitting\n                                        the CORS headers. The cross-origin request fails on the client side.\n                                        Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                        Conversely, if the request `Origin` matches one of the configured\n                                        allowed origins, the gateway sets the response header\n                                        `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                        header provided by the client.\n\n                                        When config has the wildcard (\"*\") in allowOrigins, and the request\n                                        is not credentialed (e.g., it is a preflight request), the\n                                        `Access-Control-Allow-Origin` response header either contains the\n                                        wildcard as well or the Origin from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Origin` response header. When\n                                        also the `AllowCredentials` field is true and `AllowOrigins` field\n                                        specified with the `*` wildcard, the gateway must return a single origin\n                                        in the value of the `Access-Control-Allow-Origin` response header,\n                                        instead of specifying the `*` wildcard. The value of the header\n                                        `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                        the client.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                          encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                          scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                          URIs that include an authority MUST include a fully qualified domain name or\n                                          IP address as the host.\n                                        maxLength: 253\n                                        minLength: 1\n                                        pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowOrigins cannot contain '*' alongside\n                                          other origins\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    exposeHeaders:\n                                      description: |-\n                                        ExposeHeaders indicates which HTTP response headers can be exposed\n                                        to client-side scripts in response to a cross-origin request.\n\n                                        A CORS-safelisted response header is an HTTP header in a CORS response\n                                        that it is considered safe to expose to the client scripts.\n                                        The CORS-safelisted response headers include the following headers:\n                                        `Cache-Control`\n                                        `Content-Language`\n                                        `Content-Length`\n                                        `Content-Type`\n                                        `Expires`\n                                        `Last-Modified`\n                                        `Pragma`\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                        The CORS-safelisted response headers are exposed to client by default.\n\n                                        When an HTTP header name is specified using the `ExposeHeaders` field,\n                                        this additional header will be exposed as part of the response to the\n                                        client.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        A wildcard indicates that the responses with all HTTP headers are exposed\n                                        to clients. The `Access-Control-Expose-Headers` response header can only\n                                        use `*` wildcard as value when the request is not credentialed.\n\n                                        When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                        the request is credentialed, the gateway cannot use the `*` wildcard in\n                                        the `Access-Control-Expose-Headers` response header.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    maxAge:\n                                      default: 5\n                                      description: |-\n                                        MaxAge indicates the duration (in seconds) for the client to cache the\n                                        results of a \"preflight\" request.\n\n                                        The information provided by the `Access-Control-Allow-Methods` and\n                                        `Access-Control-Allow-Headers` response headers can be cached by the\n                                        client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                        The default value of `Access-Control-Max-Age` response header is 5\n                                        (seconds).\n\n                                        When the `MaxAge` field is unspecified, the gateway sets the response\n                                        header \"Access-Control-Max-Age: 5\" by default.\n                                      format: int32\n                                      minimum: 1\n                                      type: integer\n                                  type: object\n                                extensionRef:\n                                  description: |-\n                                    ExtensionRef is an optional, implementation-specific extension to the\n                                    \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                                    \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                                    extended filters.\n\n                                    This filter can be used multiple times within the same rule.\n\n                                    Support: Implementation-specific\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When unspecified or empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"HTTPRoute\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                requestHeaderModifier:\n                                  description: |-\n                                    RequestHeaderModifier defines a schema for a filter that modifies request\n                                    headers.\n\n                                    Support: Core\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                requestMirror:\n                                  description: |-\n                                    RequestMirror defines a schema for a filter that mirrors requests.\n                                    Requests are sent to the specified destination, but responses from\n                                    that destination are ignored.\n\n                                    This filter can be used multiple times within the same rule. Note that\n                                    not all implementations will be able to support mirroring to multiple\n                                    backends.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef references a resource where mirrored requests are sent.\n\n                                        Mirrored requests must be sent only to a single destination endpoint\n                                        within this BackendRef, irrespective of how many endpoints are present\n                                        within this BackendRef.\n\n                                        If the referent cannot be found, this BackendRef is invalid and must be\n                                        dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                        condition on the Route status is set to `status: False` and not configure\n                                        this backend in the underlying implementation.\n\n                                        If there is a cross-namespace reference to an *existing* object\n                                        that is not allowed by a ReferenceGrant, the controller must ensure the\n                                        \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                        with the \"RefNotPermitted\" reason and not configure this backend in the\n                                        underlying implementation.\n\n                                        In either error case, the Message of the `ResolvedRefs` Condition\n                                        should be used to provide more detail about the problem.\n\n                                        Support: Extended for Kubernetes Service\n\n                                        Support: Implementation-specific for any other resource\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    fraction:\n                                      description: |-\n                                        Fraction represents the fraction of requests that should be\n                                        mirrored to BackendRef.\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      properties:\n                                        denominator:\n                                          default: 100\n                                          format: int32\n                                          minimum: 1\n                                          type: integer\n                                        numerator:\n                                          format: int32\n                                          minimum: 0\n                                          type: integer\n                                      required:\n                                      - numerator\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: numerator must be less than or equal\n                                          to denominator\n                                        rule: self.numerator <= self.denominator\n                                    percent:\n                                      description: |-\n                                        Percent represents the percentage of requests that should be\n                                        mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                        requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      format: int32\n                                      maximum: 100\n                                      minimum: 0\n                                      type: integer\n                                  required:\n                                  - backendRef\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: Only one of percent or fraction may be\n                                      specified in HTTPRequestMirrorFilter\n                                    rule: '!(has(self.percent) && has(self.fraction))'\n                                requestRedirect:\n                                  description: |-\n                                    RequestRedirect defines a schema for a filter that responds to the\n                                    request with an HTTP redirection.\n\n                                    Support: Core\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the hostname to be used in the value of the `Location`\n                                        header in the response.\n                                        When empty, the hostname in the `Host` header of the request is used.\n\n                                        Support: Core\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines parameters used to modify the path of the incoming request.\n                                        The modified path is then used to construct the `Location` header. When\n                                        empty, the request path is used as-is.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                    port:\n                                      description: |-\n                                        Port is the port to be used in the value of the `Location`\n                                        header in the response.\n\n                                        If no port is specified, the redirect port MUST be derived using the\n                                        following rules:\n\n                                        * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                          port associated with the redirect scheme. Specifically \"http\" to port 80\n                                          and \"https\" to port 443. If the redirect scheme does not have a\n                                          well-known port, the listener port of the Gateway SHOULD be used.\n                                        * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                          Listener port.\n\n                                        Implementations SHOULD NOT add the port number in the 'Location'\n                                        header in the following cases:\n\n                                        * A Location header that will use HTTP (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 80.\n                                        * A Location header that will use HTTPS (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                        Support: Extended\n                                      format: int32\n                                      maximum: 65535\n                                      minimum: 1\n                                      type: integer\n                                    scheme:\n                                      description: |-\n                                        Scheme is the scheme to be used in the value of the `Location` header in\n                                        the response. When empty, the scheme of the request is used.\n\n                                        Scheme redirects can affect the port of the redirect, for more information,\n                                        refer to the documentation for the port field of this filter.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Extended\n                                      enum:\n                                      - http\n                                      - https\n                                      type: string\n                                    statusCode:\n                                      default: 302\n                                      description: |-\n                                        StatusCode is the HTTP status code to be used in response.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Core\n                                      enum:\n                                      - 301\n                                      - 302\n                                      - 303\n                                      - 307\n                                      - 308\n                                      type: integer\n                                  type: object\n                                responseHeaderModifier:\n                                  description: |-\n                                    ResponseHeaderModifier defines a schema for a filter that modifies response\n                                    headers.\n\n                                    Support: Extended\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                type:\n                                  description: |-\n                                    Type identifies the type of filter to apply. As with other API fields,\n                                    types are classified into three conformance levels:\n\n                                    - Core: Filter types and their corresponding configuration defined by\n                                      \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                      implementations must support core filters.\n\n                                    - Extended: Filter types and their corresponding configuration defined by\n                                      \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                      are encouraged to support extended filters.\n\n                                    - Implementation-specific: Filters that are defined and supported by\n                                      specific vendors.\n                                      In the future, filters showing convergence in behavior across multiple\n                                      implementations will be considered for inclusion in extended or core\n                                      conformance levels. Filter-specific configuration for such filters\n                                      is specified using the ExtensionRef field. `Type` should be set to\n                                      \"ExtensionRef\" for custom filters.\n\n                                    Implementers are encouraged to define custom implementation types to\n                                    extend the core API with implementation-specific behavior.\n\n                                    If a reference to a custom filter type cannot be resolved, the filter\n                                    MUST NOT be skipped. Instead, requests that would have been processed by\n                                    that filter MUST receive a HTTP error response.\n\n                                    Note that values may be added to this enum, implementations\n                                    must ensure that unknown values will not cause a crash.\n\n                                    Unknown values here must result in the implementation setting the\n                                    Accepted Condition for the Route to `status: False`, with a\n                                    Reason of `UnsupportedValue`.\n                                  enum:\n                                  - RequestHeaderModifier\n                                  - ResponseHeaderModifier\n                                  - RequestMirror\n                                  - RequestRedirect\n                                  - URLRewrite\n                                  - ExtensionRef\n                                  - CORS\n                                  type: string\n                                urlRewrite:\n                                  description: |-\n                                    URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                                    Support: Extended\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the value to be used to replace the Host header value during\n                                        forwarding.\n\n                                        Support: Extended\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines a path rewrite.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                  type: object\n                              required:\n                              - type\n                              type: object\n                              x-kubernetes-validations:\n                              - message: filter.cors must be nil if the filter.type\n                                  is not CORS\n                                rule: '!(has(self.cors) && self.type != ''CORS'')'\n                              - message: filter.cors must be specified for CORS filter.type\n                                rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                              - message: filter.requestHeaderModifier must be nil\n                                  if the filter.type is not RequestHeaderModifier\n                                rule: '!(has(self.requestHeaderModifier) && self.type\n                                  != ''RequestHeaderModifier'')'\n                              - message: filter.requestHeaderModifier must be specified\n                                  for RequestHeaderModifier filter.type\n                                rule: '!(!has(self.requestHeaderModifier) && self.type\n                                  == ''RequestHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be nil\n                                  if the filter.type is not ResponseHeaderModifier\n                                rule: '!(has(self.responseHeaderModifier) && self.type\n                                  != ''ResponseHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be specified\n                                  for ResponseHeaderModifier filter.type\n                                rule: '!(!has(self.responseHeaderModifier) && self.type\n                                  == ''ResponseHeaderModifier'')'\n                              - message: filter.requestMirror must be nil if the filter.type\n                                  is not RequestMirror\n                                rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                              - message: filter.requestMirror must be specified for\n                                  RequestMirror filter.type\n                                rule: '!(!has(self.requestMirror) && self.type ==\n                                  ''RequestMirror'')'\n                              - message: filter.requestRedirect must be nil if the\n                                  filter.type is not RequestRedirect\n                                rule: '!(has(self.requestRedirect) && self.type !=\n                                  ''RequestRedirect'')'\n                              - message: filter.requestRedirect must be specified\n                                  for RequestRedirect filter.type\n                                rule: '!(!has(self.requestRedirect) && self.type ==\n                                  ''RequestRedirect'')'\n                              - message: filter.urlRewrite must be nil if the filter.type\n                                  is not URLRewrite\n                                rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                              - message: filter.urlRewrite must be specified for URLRewrite\n                                  filter.type\n                                rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                              - message: filter.extensionRef must be nil if the filter.type\n                                  is not ExtensionRef\n                                rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                              - message: filter.extensionRef must be specified for\n                                  ExtensionRef filter.type\n                                rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-type: atomic\n                            x-kubernetes-validations:\n                            - message: May specify either httpRouteFilterRequestRedirect\n                                or httpRouteFilterRequestRewrite, but not both\n                              rule: '!(self.exists(f, f.type == ''RequestRedirect'')\n                                && self.exists(f, f.type == ''URLRewrite''))'\n                            - message: RequestHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                                <= 1\n                            - message: ResponseHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                                <= 1\n                            - message: RequestRedirect filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestRedirect').size()\n                                <= 1\n                            - message: URLRewrite filter cannot be repeated\n                              rule: self.filter(f, f.type == 'URLRewrite').size()\n                                <= 1\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    filters:\n                      description: |-\n                        Filters define the filters that are applied to requests that match\n                        this rule.\n\n                        Wherever possible, implementations SHOULD implement filters in the order\n                        they are specified.\n\n                        Implementations MAY choose to implement this ordering strictly, rejecting\n                        any combination or order of filters that cannot be supported. If implementations\n                        choose a strict interpretation of filter ordering, they MUST clearly document\n                        that behavior.\n\n                        To reject an invalid combination or order of filters, implementations SHOULD\n                        consider the Route Rules with this configuration invalid. If all Route Rules\n                        in a Route are invalid, the entire Route would be considered invalid. If only\n                        a portion of Route Rules are invalid, implementations MUST set the\n                        \"PartiallyInvalid\" condition for the Route.\n\n                        Conformance-levels at this level are defined based on the type of filter:\n\n                        - ALL core filters MUST be supported by all implementations.\n                        - Implementers are encouraged to support extended filters.\n                        - Implementation-specific custom filters have no API guarantees across\n                          implementations.\n\n                        Specifying the same filter multiple times is not supported unless explicitly\n                        indicated in the filter.\n\n                        All filters are expected to be compatible with each other except for the\n                        URLRewrite and RequestRedirect filters, which may not be combined. If an\n                        implementation cannot support other combinations of filters, they must clearly\n                        document that limitation. In cases where incompatible or unsupported\n                        filters are specified and cause the `Accepted` condition to be set to status\n                        `False`, implementations may use the `IncompatibleFilters` reason to specify\n                        this configuration error.\n\n                        Support: Core\n                      items:\n                        description: |-\n                          HTTPRouteFilter defines processing steps that must be completed during the\n                          request or response lifecycle. HTTPRouteFilters are meant as an extension\n                          point to express processing that may be done in Gateway implementations. Some\n                          examples include request or response modification, implementing\n                          authentication strategies, rate-limiting, and traffic shaping. API\n                          guarantee/conformance is defined based on the type of the filter.\n                        properties:\n                          cors:\n                            description: |-\n                              CORS defines a schema for a filter that responds to the\n                              cross-origin request based on HTTP response header.\n\n                              Support: Extended\n                            properties:\n                              allowCredentials:\n                                description: |-\n                                  AllowCredentials indicates whether the actual cross-origin request allows\n                                  to include credentials.\n\n                                  When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                  response header with value true (case-sensitive).\n\n                                  When set to false or omitted the gateway will omit the header\n                                  `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                  behavior).\n\n                                  Support: Extended\n                                type: boolean\n                              allowHeaders:\n                                description: |-\n                                  AllowHeaders indicates which HTTP request headers are supported for\n                                  accessing the requested resource.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  When the `AllowHeaders` field is configured with one or more headers, the\n                                  gateway must return the `Access-Control-Allow-Headers` response header\n                                  which value is present in the `AllowHeaders` field.\n\n                                  If any header name in the `Access-Control-Request-Headers` request header\n                                  is not included in the list of header names specified by the response\n                                  header `Access-Control-Allow-Headers`, it will present an error on the\n                                  client side.\n\n                                  If any header name in the `Access-Control-Allow-Headers` response header\n                                  does not recognize by the client, it will also occur an error on the\n                                  client side.\n\n                                  A wildcard indicates that the requests with all HTTP headers are allowed.\n                                  If config contains the wildcard \"*\" in allowHeaders and the request is\n                                  not credentialed, the `Access-Control-Allow-Headers` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Headers from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Headers` response header. When\n                                  also the `AllowCredentials` field is true and `AllowHeaders` field\n                                  is specified with the `*` wildcard, the gateway must specify one or more\n                                  HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                  header. The value of the header `Access-Control-Allow-Headers` is same as\n                                  the `Access-Control-Request-Headers` header provided by the client. If\n                                  the header `Access-Control-Request-Headers` is not included in the\n                                  request, the gateway will omit the `Access-Control-Allow-Headers`\n                                  response header, instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowHeaders cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowMethods:\n                                description: |-\n                                  AllowMethods indicates which HTTP methods are supported for accessing the\n                                  requested resource.\n\n                                  Valid values are any method defined by RFC9110, along with the special\n                                  value `*`, which represents all HTTP methods are allowed.\n\n                                  Method names are case-sensitive, so these values are also case-sensitive.\n                                  (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                  Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                  response header are separated by a comma (\",\").\n\n                                  A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                  CORS-safelisted methods are always allowed, regardless of whether they\n                                  are specified in the `AllowMethods` field.\n\n                                  When the `AllowMethods` field is configured with one or more methods, the\n                                  gateway must return the `Access-Control-Allow-Methods` response header\n                                  which value is present in the `AllowMethods` field.\n\n                                  If the HTTP method of the `Access-Control-Request-Method` request header\n                                  is not included in the list of methods specified by the response header\n                                  `Access-Control-Allow-Methods`, it will present an error on the client\n                                  side.\n\n                                  If config contains the wildcard \"*\" in allowMethods and the request is\n                                  not credentialed, the `Access-Control-Allow-Methods` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Method from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Methods` response header. When\n                                  also the `AllowCredentials` field is true and `AllowMethods` field\n                                  specified with the `*` wildcard, the gateway must specify one HTTP method\n                                  in the value of the Access-Control-Allow-Methods response header. The\n                                  value of the header `Access-Control-Allow-Methods` is same as the\n                                  `Access-Control-Request-Method` header provided by the client. If the\n                                  header `Access-Control-Request-Method` is not included in the request,\n                                  the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                  instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  enum:\n                                  - GET\n                                  - HEAD\n                                  - POST\n                                  - PUT\n                                  - DELETE\n                                  - CONNECT\n                                  - OPTIONS\n                                  - TRACE\n                                  - PATCH\n                                  - '*'\n                                  type: string\n                                maxItems: 9\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowMethods cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowOrigins:\n                                description: |-\n                                  AllowOrigins indicates whether the response can be shared with requested\n                                  resource from the given `Origin`.\n\n                                  The `Origin` consists of a scheme and a host, with an optional port, and\n                                  takes the form `<scheme>://<host>(:<port>)`.\n\n                                  Valid values for scheme are: `http` and `https`.\n\n                                  Valid values for port are any integer between 1 and 65535 (the list of\n                                  available TCP/UDP ports). Note that, if not included, port `80` is\n                                  assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                  origins. This may affect origin matching.\n\n                                  The host part of the origin may contain the wildcard character `*`. These\n                                  wildcard characters behave as follows:\n\n                                  * `*` is a greedy match to the _left_, including any number of\n                                    DNS labels to the left of its position. This also means that\n                                    `*` will include any number of period `.` characters to the\n                                    left of its position.\n                                  * A wildcard by itself matches all hosts.\n\n                                  An origin value that includes _only_ the `*` character indicates requests\n                                  from all `Origin`s are allowed.\n\n                                  When the `AllowOrigins` field is configured with multiple origins, it\n                                  means the server supports clients from multiple origins. If the request\n                                  `Origin` matches the configured allowed origins, the gateway must return\n                                  the given `Origin` and sets value of the header\n                                  `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                  client.\n\n                                  The status code of a successful response to a \"preflight\" request is\n                                  always an OK status (i.e., 204 or 200).\n\n                                  If the request `Origin` does not match the configured allowed origins,\n                                  the gateway returns 204/200 response but doesn't set the relevant\n                                  cross-origin response headers. Alternatively, the gateway responds with\n                                  403 status to the \"preflight\" request is denied, coupled with omitting\n                                  the CORS headers. The cross-origin request fails on the client side.\n                                  Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                  Conversely, if the request `Origin` matches one of the configured\n                                  allowed origins, the gateway sets the response header\n                                  `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                  header provided by the client.\n\n                                  When config has the wildcard (\"*\") in allowOrigins, and the request\n                                  is not credentialed (e.g., it is a preflight request), the\n                                  `Access-Control-Allow-Origin` response header either contains the\n                                  wildcard as well or the Origin from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Origin` response header. When\n                                  also the `AllowCredentials` field is true and `AllowOrigins` field\n                                  specified with the `*` wildcard, the gateway must return a single origin\n                                  in the value of the `Access-Control-Allow-Origin` response header,\n                                  instead of specifying the `*` wildcard. The value of the header\n                                  `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                  the client.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                    encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                    scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                    URIs that include an authority MUST include a fully qualified domain name or\n                                    IP address as the host.\n                                  maxLength: 253\n                                  minLength: 1\n                                  pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowOrigins cannot contain '*' alongside\n                                    other origins\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              exposeHeaders:\n                                description: |-\n                                  ExposeHeaders indicates which HTTP response headers can be exposed\n                                  to client-side scripts in response to a cross-origin request.\n\n                                  A CORS-safelisted response header is an HTTP header in a CORS response\n                                  that it is considered safe to expose to the client scripts.\n                                  The CORS-safelisted response headers include the following headers:\n                                  `Cache-Control`\n                                  `Content-Language`\n                                  `Content-Length`\n                                  `Content-Type`\n                                  `Expires`\n                                  `Last-Modified`\n                                  `Pragma`\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                  The CORS-safelisted response headers are exposed to client by default.\n\n                                  When an HTTP header name is specified using the `ExposeHeaders` field,\n                                  this additional header will be exposed as part of the response to the\n                                  client.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  A wildcard indicates that the responses with all HTTP headers are exposed\n                                  to clients. The `Access-Control-Expose-Headers` response header can only\n                                  use `*` wildcard as value when the request is not credentialed.\n\n                                  When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                  the request is credentialed, the gateway cannot use the `*` wildcard in\n                                  the `Access-Control-Expose-Headers` response header.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                              maxAge:\n                                default: 5\n                                description: |-\n                                  MaxAge indicates the duration (in seconds) for the client to cache the\n                                  results of a \"preflight\" request.\n\n                                  The information provided by the `Access-Control-Allow-Methods` and\n                                  `Access-Control-Allow-Headers` response headers can be cached by the\n                                  client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                  The default value of `Access-Control-Max-Age` response header is 5\n                                  (seconds).\n\n                                  When the `MaxAge` field is unspecified, the gateway sets the response\n                                  header \"Access-Control-Max-Age: 5\" by default.\n                                format: int32\n                                minimum: 1\n                                type: integer\n                            type: object\n                          extensionRef:\n                            description: |-\n                              ExtensionRef is an optional, implementation-specific extension to the\n                              \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                              \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                              extended filters.\n\n                              This filter can be used multiple times within the same rule.\n\n                              Support: Implementation-specific\n                            properties:\n                              group:\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is kind of the referent. For example\n                                  \"HTTPRoute\" or \"Service\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                            required:\n                            - group\n                            - kind\n                            - name\n                            type: object\n                          requestHeaderModifier:\n                            description: |-\n                              RequestHeaderModifier defines a schema for a filter that modifies request\n                              headers.\n\n                              Support: Core\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          requestMirror:\n                            description: |-\n                              RequestMirror defines a schema for a filter that mirrors requests.\n                              Requests are sent to the specified destination, but responses from\n                              that destination are ignored.\n\n                              This filter can be used multiple times within the same rule. Note that\n                              not all implementations will be able to support mirroring to multiple\n                              backends.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef references a resource where mirrored requests are sent.\n\n                                  Mirrored requests must be sent only to a single destination endpoint\n                                  within this BackendRef, irrespective of how many endpoints are present\n                                  within this BackendRef.\n\n                                  If the referent cannot be found, this BackendRef is invalid and must be\n                                  dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                  condition on the Route status is set to `status: False` and not configure\n                                  this backend in the underlying implementation.\n\n                                  If there is a cross-namespace reference to an *existing* object\n                                  that is not allowed by a ReferenceGrant, the controller must ensure the\n                                  \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                  with the \"RefNotPermitted\" reason and not configure this backend in the\n                                  underlying implementation.\n\n                                  In either error case, the Message of the `ResolvedRefs` Condition\n                                  should be used to provide more detail about the problem.\n\n                                  Support: Extended for Kubernetes Service\n\n                                  Support: Implementation-specific for any other resource\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              fraction:\n                                description: |-\n                                  Fraction represents the fraction of requests that should be\n                                  mirrored to BackendRef.\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                properties:\n                                  denominator:\n                                    default: 100\n                                    format: int32\n                                    minimum: 1\n                                    type: integer\n                                  numerator:\n                                    format: int32\n                                    minimum: 0\n                                    type: integer\n                                required:\n                                - numerator\n                                type: object\n                                x-kubernetes-validations:\n                                - message: numerator must be less than or equal to\n                                    denominator\n                                  rule: self.numerator <= self.denominator\n                              percent:\n                                description: |-\n                                  Percent represents the percentage of requests that should be\n                                  mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                  requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                format: int32\n                                maximum: 100\n                                minimum: 0\n                                type: integer\n                            required:\n                            - backendRef\n                            type: object\n                            x-kubernetes-validations:\n                            - message: Only one of percent or fraction may be specified\n                                in HTTPRequestMirrorFilter\n                              rule: '!(has(self.percent) && has(self.fraction))'\n                          requestRedirect:\n                            description: |-\n                              RequestRedirect defines a schema for a filter that responds to the\n                              request with an HTTP redirection.\n\n                              Support: Core\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the hostname to be used in the value of the `Location`\n                                  header in the response.\n                                  When empty, the hostname in the `Host` header of the request is used.\n\n                                  Support: Core\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines parameters used to modify the path of the incoming request.\n                                  The modified path is then used to construct the `Location` header. When\n                                  empty, the request path is used as-is.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                              port:\n                                description: |-\n                                  Port is the port to be used in the value of the `Location`\n                                  header in the response.\n\n                                  If no port is specified, the redirect port MUST be derived using the\n                                  following rules:\n\n                                  * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                    port associated with the redirect scheme. Specifically \"http\" to port 80\n                                    and \"https\" to port 443. If the redirect scheme does not have a\n                                    well-known port, the listener port of the Gateway SHOULD be used.\n                                  * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                    Listener port.\n\n                                  Implementations SHOULD NOT add the port number in the 'Location'\n                                  header in the following cases:\n\n                                  * A Location header that will use HTTP (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 80.\n                                  * A Location header that will use HTTPS (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                  Support: Extended\n                                format: int32\n                                maximum: 65535\n                                minimum: 1\n                                type: integer\n                              scheme:\n                                description: |-\n                                  Scheme is the scheme to be used in the value of the `Location` header in\n                                  the response. When empty, the scheme of the request is used.\n\n                                  Scheme redirects can affect the port of the redirect, for more information,\n                                  refer to the documentation for the port field of this filter.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Extended\n                                enum:\n                                - http\n                                - https\n                                type: string\n                              statusCode:\n                                default: 302\n                                description: |-\n                                  StatusCode is the HTTP status code to be used in response.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Core\n                                enum:\n                                - 301\n                                - 302\n                                - 303\n                                - 307\n                                - 308\n                                type: integer\n                            type: object\n                          responseHeaderModifier:\n                            description: |-\n                              ResponseHeaderModifier defines a schema for a filter that modifies response\n                              headers.\n\n                              Support: Extended\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          type:\n                            description: |-\n                              Type identifies the type of filter to apply. As with other API fields,\n                              types are classified into three conformance levels:\n\n                              - Core: Filter types and their corresponding configuration defined by\n                                \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                implementations must support core filters.\n\n                              - Extended: Filter types and their corresponding configuration defined by\n                                \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                are encouraged to support extended filters.\n\n                              - Implementation-specific: Filters that are defined and supported by\n                                specific vendors.\n                                In the future, filters showing convergence in behavior across multiple\n                                implementations will be considered for inclusion in extended or core\n                                conformance levels. Filter-specific configuration for such filters\n                                is specified using the ExtensionRef field. `Type` should be set to\n                                \"ExtensionRef\" for custom filters.\n\n                              Implementers are encouraged to define custom implementation types to\n                              extend the core API with implementation-specific behavior.\n\n                              If a reference to a custom filter type cannot be resolved, the filter\n                              MUST NOT be skipped. Instead, requests that would have been processed by\n                              that filter MUST receive a HTTP error response.\n\n                              Note that values may be added to this enum, implementations\n                              must ensure that unknown values will not cause a crash.\n\n                              Unknown values here must result in the implementation setting the\n                              Accepted Condition for the Route to `status: False`, with a\n                              Reason of `UnsupportedValue`.\n                            enum:\n                            - RequestHeaderModifier\n                            - ResponseHeaderModifier\n                            - RequestMirror\n                            - RequestRedirect\n                            - URLRewrite\n                            - ExtensionRef\n                            - CORS\n                            type: string\n                          urlRewrite:\n                            description: |-\n                              URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                              Support: Extended\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the value to be used to replace the Host header value during\n                                  forwarding.\n\n                                  Support: Extended\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines a path rewrite.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                            type: object\n                        required:\n                        - type\n                        type: object\n                        x-kubernetes-validations:\n                        - message: filter.cors must be nil if the filter.type is not\n                            CORS\n                          rule: '!(has(self.cors) && self.type != ''CORS'')'\n                        - message: filter.cors must be specified for CORS filter.type\n                          rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                        - message: filter.requestHeaderModifier must be nil if the\n                            filter.type is not RequestHeaderModifier\n                          rule: '!(has(self.requestHeaderModifier) && self.type !=\n                            ''RequestHeaderModifier'')'\n                        - message: filter.requestHeaderModifier must be specified\n                            for RequestHeaderModifier filter.type\n                          rule: '!(!has(self.requestHeaderModifier) && self.type ==\n                            ''RequestHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be nil if the\n                            filter.type is not ResponseHeaderModifier\n                          rule: '!(has(self.responseHeaderModifier) && self.type !=\n                            ''ResponseHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be specified\n                            for ResponseHeaderModifier filter.type\n                          rule: '!(!has(self.responseHeaderModifier) && self.type\n                            == ''ResponseHeaderModifier'')'\n                        - message: filter.requestMirror must be nil if the filter.type\n                            is not RequestMirror\n                          rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                        - message: filter.requestMirror must be specified for RequestMirror\n                            filter.type\n                          rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'\n                        - message: filter.requestRedirect must be nil if the filter.type\n                            is not RequestRedirect\n                          rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')'\n                        - message: filter.requestRedirect must be specified for RequestRedirect\n                            filter.type\n                          rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')'\n                        - message: filter.urlRewrite must be nil if the filter.type\n                            is not URLRewrite\n                          rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                        - message: filter.urlRewrite must be specified for URLRewrite\n                            filter.type\n                          rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                        - message: filter.extensionRef must be nil if the filter.type\n                            is not ExtensionRef\n                          rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                        - message: filter.extensionRef must be specified for ExtensionRef\n                            filter.type\n                          rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                      x-kubernetes-validations:\n                      - message: May specify either httpRouteFilterRequestRedirect\n                          or httpRouteFilterRequestRewrite, but not both\n                        rule: '!(self.exists(f, f.type == ''RequestRedirect'') &&\n                          self.exists(f, f.type == ''URLRewrite''))'\n                      - message: RequestHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                          <= 1\n                      - message: ResponseHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                          <= 1\n                      - message: RequestRedirect filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestRedirect').size() <=\n                          1\n                      - message: URLRewrite filter cannot be repeated\n                        rule: self.filter(f, f.type == 'URLRewrite').size() <= 1\n                    matches:\n                      default:\n                      - path:\n                          type: PathPrefix\n                          value: /\n                      description: |-\n                        Matches define conditions used for matching the rule against incoming\n                        HTTP requests. Each match is independent, i.e. this rule will be matched\n                        if **any** one of the matches is satisfied.\n\n                        For example, take the following matches configuration:\n\n                        ```\n                        matches:\n                        - path:\n                            value: \"/foo\"\n                          headers:\n                          - name: \"version\"\n                            value: \"v2\"\n                        - path:\n                            value: \"/v2/foo\"\n                        ```\n\n                        For a request to match against this rule, a request must satisfy\n                        EITHER of the two conditions:\n\n                        - path prefixed with `/foo` AND contains the header `version: v2`\n                        - path prefix of `/v2/foo`\n\n                        See the documentation for HTTPRouteMatch on how to specify multiple\n                        match conditions that should be ANDed together.\n\n                        If no matches are specified, the default is a prefix\n                        path match on \"/\", which has the effect of matching every\n                        HTTP request.\n\n                        Proxy or Load Balancer routing configuration generated from HTTPRoutes\n                        MUST prioritize matches based on the following criteria, continuing on\n                        ties. Across all rules specified on applicable Routes, precedence must be\n                        given to the match having:\n\n                        * \"Exact\" path match.\n                        * \"Prefix\" path match with largest number of characters.\n                        * Method match.\n                        * Largest number of header matches.\n                        * Largest number of query param matches.\n\n                        Note: The precedence of RegularExpression path matches are implementation-specific.\n\n                        If ties still exist across multiple Routes, matching precedence MUST be\n                        determined in order of the following criteria, continuing on ties:\n\n                        * The oldest Route based on creation timestamp.\n                        * The Route appearing first in alphabetical order by\n                          \"{namespace}/{name}\".\n\n                        If ties still exist within an HTTPRoute, matching precedence MUST be granted\n                        to the FIRST matching rule (in list order) with a match meeting the above\n                        criteria.\n\n                        When no rules matching a request have been successfully attached to the\n                        parent a request is coming from, a HTTP 404 status code MUST be returned.\n                      items:\n                        description: \"HTTPRouteMatch defines the predicate used to\n                          match requests to a given\\naction. Multiple match types\n                          are ANDed together, i.e. the match will\\nevaluate to true\n                          only if all conditions are satisfied.\\n\\nFor example, the\n                          match below will match a HTTP request only if its path\\nstarts\n                          with `/foo` AND it contains the `version: v1` header:\\n\\n```\\nmatch:\\n\\n\\tpath:\\n\\t\n                          \\ value: \\\"/foo\\\"\\n\\theaders:\\n\\t- name: \\\"version\\\"\\n\\t\n                          \\ value \\\"v1\\\"\\n\\n```\"\n                        properties:\n                          headers:\n                            description: |-\n                              Headers specifies HTTP request header matchers. Multiple match values are\n                              ANDed together, meaning, a request must match all the specified headers\n                              to select the route.\n                            items:\n                              description: |-\n                                HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request\n                                headers.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                    case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                    If multiple entries specify equivalent header names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent header name MUST be ignored. Due to the\n                                    case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                    equivalent.\n\n                                    When a header is repeated in an HTTP request, it is\n                                    implementation-specific behavior as to how this is represented.\n                                    Generally, proxies should follow the guidance from the RFC:\n                                    https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding\n                                    processing a repeated header, with special handling for \"Set-Cookie\".\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the header.\n\n                                    Support: Core (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression HeaderMatchType has implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other dialects\n                                    of regular expressions. Please read the implementation's documentation to\n                                    determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of HTTP Header to\n                                    be matched.\n                                  maxLength: 4096\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                          method:\n                            description: |-\n                              Method specifies HTTP method matcher.\n                              When specified, this route will be matched only if the request has the\n                              specified method.\n\n                              Support: Extended\n                            enum:\n                            - GET\n                            - HEAD\n                            - POST\n                            - PUT\n                            - DELETE\n                            - CONNECT\n                            - OPTIONS\n                            - TRACE\n                            - PATCH\n                            type: string\n                          path:\n                            default:\n                              type: PathPrefix\n                              value: /\n                            description: |-\n                              Path specifies a HTTP request path matcher. If this field is not\n                              specified, a default prefix match on the \"/\" path is provided.\n                            properties:\n                              type:\n                                default: PathPrefix\n                                description: |-\n                                  Type specifies how to match against the path Value.\n\n                                  Support: Core (Exact, PathPrefix)\n\n                                  Support: Implementation-specific (RegularExpression)\n                                enum:\n                                - Exact\n                                - PathPrefix\n                                - RegularExpression\n                                type: string\n                              value:\n                                default: /\n                                description: Value of the HTTP path to match against.\n                                maxLength: 1024\n                                type: string\n                            type: object\n                            x-kubernetes-validations:\n                            - message: value must be an absolute path and start with\n                                '/' when type one of ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'')\n                                : true'\n                            - message: must not contain '//' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'')\n                                : true'\n                            - message: must not contain '/./' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'')\n                                : true'\n                            - message: must not contain '/../' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'')\n                                : true'\n                            - message: must not contain '%2f' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'')\n                                : true'\n                            - message: must not contain '%2F' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'')\n                                : true'\n                            - message: must not contain '#' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'')\n                                : true'\n                            - message: must not end with '/..' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'')\n                                : true'\n                            - message: must not end with '/.' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'')\n                                : true'\n                            - message: type must be one of ['Exact', 'PathPrefix',\n                                'RegularExpression']\n                              rule: self.type in ['Exact','PathPrefix'] || self.type\n                                == 'RegularExpression'\n                            - message: must only contain valid characters (matching\n                                ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$)\n                                for types ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r\"\"\"^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$\"\"\")\n                                : true'\n                          queryParams:\n                            description: |-\n                              QueryParams specifies HTTP query parameter matchers. Multiple match\n                              values are ANDed together, meaning, a request must match all the\n                              specified query parameters to select the route.\n\n                              Support: Extended\n                            items:\n                              description: |-\n                                HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP\n                                query parameters.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP query param to be matched. This must be an\n                                    exact string match. (See\n                                    https://tools.ietf.org/html/rfc7230#section-2.7.3).\n\n                                    If multiple entries specify equivalent query param names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent query param name MUST be ignored.\n\n                                    If a query param is repeated in an HTTP request, the behavior is\n                                    purposely left undefined, since different data planes have different\n                                    capabilities. However, it is *recommended* that implementations should\n                                    match against the first value of the param if the data plane supports it,\n                                    as this behavior is expected in other load balancing contexts outside of\n                                    the Gateway API.\n\n                                    Users SHOULD NOT route traffic based on repeated query params to guard\n                                    themselves against potential differences in the implementations.\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the query parameter.\n\n                                    Support: Extended (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression QueryParamMatchType has Implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other\n                                    dialects of regular expressions. Please read the implementation's\n                                    documentation to determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of HTTP query param\n                                    to be matched.\n                                  maxLength: 1024\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                        type: object\n                      maxItems: 64\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    timeouts:\n                      description: |-\n                        Timeouts defines the timeouts that can be configured for an HTTP request.\n\n                        Support: Extended\n                      properties:\n                        backendRequest:\n                          description: |-\n                            BackendRequest specifies a timeout for an individual request from the gateway\n                            to a backend. This covers the time from when the request first starts being\n                            sent from the gateway to when the full response has been received from the backend.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            An entire client HTTP transaction with a gateway, covered by the Request timeout,\n                            may result in more than one call from the gateway to the destination backend,\n                            for example, if automatic retries are supported.\n\n                            The value of BackendRequest must be a Gateway API Duration string as defined by\n                            GEP-2257.  When this field is unspecified, its behavior is implementation-specific;\n                            when specified, the value of BackendRequest must be no more than the value of the\n                            Request timeout (since the Request timeout encompasses the BackendRequest timeout).\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        request:\n                          description: |-\n                            Request specifies the maximum duration for a gateway to respond to an HTTP request.\n                            If the gateway has not been able to respond before this deadline is met, the gateway\n                            MUST return a timeout error.\n\n                            For example, setting the `rules.timeouts.request` field to the value `10s` in an\n                            `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds\n                            to complete.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            This timeout is intended to cover as close to the whole request-response transaction\n                            as possible although an implementation MAY choose to start the timeout after the entire\n                            request stream has been received instead of immediately after the transaction is\n                            initiated by the client.\n\n                            The value of Request is a Gateway API Duration string as defined by GEP-2257. When this\n                            field is unspecified, request timeout behavior is implementation-specific.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: backendRequest timeout cannot be longer than request\n                          timeout\n                        rule: '!(has(self.request) && has(self.backendRequest) &&\n                          duration(self.request) != duration(''0s'') && duration(self.backendRequest)\n                          > duration(self.request))'\n                  type: object\n                  x-kubernetes-validations:\n                  - message: RequestRedirect filter must not be used together with\n                      backendRefs\n                    rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ?\n                      (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))):\n                      true'\n                  - message: When using RequestRedirect filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      ? ((size(self.matches) != 1 || !has(self.matches[0].path) ||\n                      self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: When using URLRewrite filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                  - message: Within backendRefs, when using RequestRedirect filter\n                      with path.replacePrefixMatch, exactly one PathPrefix match must\n                      be specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      )) ? ((size(self.matches) != 1 || !has(self.matches[0].path)\n                      || self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: Within backendRefs, When using URLRewrite filter with\n                      path.replacePrefixMatch, exactly one PathPrefix match must be\n                      specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: While 16 rules and 64 matches per rule are allowed, the\n                    total number of matches across all rules in a route must be less\n                    than 128\n                  rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size()\n                    > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size()\n                    : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size()\n                    > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size()\n                    : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size()\n                    > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size()\n                    : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size()\n                    > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size()\n                    : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size()\n                    > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size()\n                    : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128'\n            type: object\n          status:\n            description: Status defines the current state of HTTPRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .spec.hostnames\n      name: Hostnames\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          HTTPRoute provides a way to route HTTP requests. This includes the capability\n          to match requests by hostname, path, header, or query param. Filters can be\n          used to specify additional processing steps. Backends specify where matching\n          requests should be routed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of HTTPRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of hostnames that should match against the HTTP Host\n                  header to select a HTTPRoute used to process the request. Implementations\n                  MUST ignore any port value specified in the HTTP Host header while\n                  performing a match and (absent of any applicable header modification\n                  configuration) MUST forward this header unmodified to the backend.\n\n                  Valid values for Hostnames are determined by RFC 1123 definition of a\n                  hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and HTTPRoute, there\n                  must be at least one intersecting hostname for the HTTPRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches HTTPRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `*.example.com`, `test.example.com`, and `foo.test.example.com` would\n                    all match. On the other hand, `example.com` and `test.example.net` would\n                    not match.\n\n                  Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                  as a suffix match. That means that a match for `*.example.com` would match\n                  both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\n                  If both the Listener and HTTPRoute have specified hostnames, any\n                  HTTPRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  HTTPRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` must not be considered for a match.\n\n                  If both the Listener and HTTPRoute have specified hostnames, and none\n                  match with the criteria above, then the HTTPRoute is not accepted. The\n                  implementation must raise an 'Accepted' Condition with a status of\n                  `False` in the corresponding RouteParentStatus.\n\n                  In the event that multiple HTTPRoutes specify intersecting hostnames (e.g.\n                  overlapping wildcard matching and exact matching hostnames), precedence must\n                  be given to rules from the HTTPRoute with the largest number of:\n\n                  * Characters in a matching non-wildcard hostname.\n                  * Characters in a matching hostname.\n\n                  If ties exist across multiple Routes, the matching precedence rules for\n                  HTTPRouteMatches takes over.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''')) : true))'\n                - message: sectionName must be unique when parentRefs includes 2 or\n                    more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              rules:\n                default:\n                - matches:\n                  - path:\n                      type: PathPrefix\n                      value: /\n                description: Rules are a list of HTTP matchers, filters and actions.\n                items:\n                  description: |-\n                    HTTPRouteRule defines semantics for matching an HTTP request based on\n                    conditions (matches), processing it (filters), and forwarding the request to\n                    an API object (backendRefs).\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent.\n\n                        Failure behavior here depends on how many BackendRefs are specified and\n                        how many are invalid.\n\n                        If *all* entries in BackendRefs are invalid, and there are also no filters\n                        specified in this route rule, *all* traffic which matches this rule MUST\n                        receive a 500 status code.\n\n                        See the HTTPBackendRef definition for the rules about what makes a single\n                        HTTPBackendRef invalid.\n\n                        When a HTTPBackendRef is invalid, 500 status codes MUST be returned for\n                        requests that would have otherwise been routed to an invalid backend. If\n                        multiple backends are specified, and some are invalid, the proportion of\n                        requests that would otherwise have been routed to an invalid backend\n                        MUST receive a 500 status code.\n\n                        For example, if two backends are specified with equal weights, and one is\n                        invalid, 50 percent of traffic must receive a 500. Implementations may\n                        choose how that 50 percent is determined.\n\n                        When a HTTPBackendRef refers to a Service that has no ready endpoints,\n                        implementations SHOULD return a 503 for requests to that backend instead.\n                        If an implementation chooses to do this, all of the above rules for 500 responses\n                        MUST also apply for responses that return a 503.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Core\n                      items:\n                        description: |-\n                          HTTPBackendRef defines how a HTTPRoute forwards a HTTP request.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n                        properties:\n                          filters:\n                            description: |-\n                              Filters defined at this level should be executed if and only if the\n                              request is being forwarded to the backend defined here.\n\n                              Support: Implementation-specific (For broader support of filters, use the\n                              Filters field in HTTPRouteRule.)\n                            items:\n                              description: |-\n                                HTTPRouteFilter defines processing steps that must be completed during the\n                                request or response lifecycle. HTTPRouteFilters are meant as an extension\n                                point to express processing that may be done in Gateway implementations. Some\n                                examples include request or response modification, implementing\n                                authentication strategies, rate-limiting, and traffic shaping. API\n                                guarantee/conformance is defined based on the type of the filter.\n                              properties:\n                                cors:\n                                  description: |-\n                                    CORS defines a schema for a filter that responds to the\n                                    cross-origin request based on HTTP response header.\n\n                                    Support: Extended\n                                  properties:\n                                    allowCredentials:\n                                      description: |-\n                                        AllowCredentials indicates whether the actual cross-origin request allows\n                                        to include credentials.\n\n                                        When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                        response header with value true (case-sensitive).\n\n                                        When set to false or omitted the gateway will omit the header\n                                        `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                        behavior).\n\n                                        Support: Extended\n                                      type: boolean\n                                    allowHeaders:\n                                      description: |-\n                                        AllowHeaders indicates which HTTP request headers are supported for\n                                        accessing the requested resource.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        When the `AllowHeaders` field is configured with one or more headers, the\n                                        gateway must return the `Access-Control-Allow-Headers` response header\n                                        which value is present in the `AllowHeaders` field.\n\n                                        If any header name in the `Access-Control-Request-Headers` request header\n                                        is not included in the list of header names specified by the response\n                                        header `Access-Control-Allow-Headers`, it will present an error on the\n                                        client side.\n\n                                        If any header name in the `Access-Control-Allow-Headers` response header\n                                        does not recognize by the client, it will also occur an error on the\n                                        client side.\n\n                                        A wildcard indicates that the requests with all HTTP headers are allowed.\n                                        If config contains the wildcard \"*\" in allowHeaders and the request is\n                                        not credentialed, the `Access-Control-Allow-Headers` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Headers from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Headers` response header. When\n                                        also the `AllowCredentials` field is true and `AllowHeaders` field\n                                        is specified with the `*` wildcard, the gateway must specify one or more\n                                        HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                        header. The value of the header `Access-Control-Allow-Headers` is same as\n                                        the `Access-Control-Request-Headers` header provided by the client. If\n                                        the header `Access-Control-Request-Headers` is not included in the\n                                        request, the gateway will omit the `Access-Control-Allow-Headers`\n                                        response header, instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowHeaders cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowMethods:\n                                      description: |-\n                                        AllowMethods indicates which HTTP methods are supported for accessing the\n                                        requested resource.\n\n                                        Valid values are any method defined by RFC9110, along with the special\n                                        value `*`, which represents all HTTP methods are allowed.\n\n                                        Method names are case-sensitive, so these values are also case-sensitive.\n                                        (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                        Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                        response header are separated by a comma (\",\").\n\n                                        A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                        CORS-safelisted methods are always allowed, regardless of whether they\n                                        are specified in the `AllowMethods` field.\n\n                                        When the `AllowMethods` field is configured with one or more methods, the\n                                        gateway must return the `Access-Control-Allow-Methods` response header\n                                        which value is present in the `AllowMethods` field.\n\n                                        If the HTTP method of the `Access-Control-Request-Method` request header\n                                        is not included in the list of methods specified by the response header\n                                        `Access-Control-Allow-Methods`, it will present an error on the client\n                                        side.\n\n                                        If config contains the wildcard \"*\" in allowMethods and the request is\n                                        not credentialed, the `Access-Control-Allow-Methods` response header\n                                        can either use the `*` wildcard or the value of\n                                        Access-Control-Request-Method from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Methods` response header. When\n                                        also the `AllowCredentials` field is true and `AllowMethods` field\n                                        specified with the `*` wildcard, the gateway must specify one HTTP method\n                                        in the value of the Access-Control-Allow-Methods response header. The\n                                        value of the header `Access-Control-Allow-Methods` is same as the\n                                        `Access-Control-Request-Method` header provided by the client. If the\n                                        header `Access-Control-Request-Method` is not included in the request,\n                                        the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                        instead of specifying the `*` wildcard.\n\n                                        Support: Extended\n                                      items:\n                                        enum:\n                                        - GET\n                                        - HEAD\n                                        - POST\n                                        - PUT\n                                        - DELETE\n                                        - CONNECT\n                                        - OPTIONS\n                                        - TRACE\n                                        - PATCH\n                                        - '*'\n                                        type: string\n                                      maxItems: 9\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowMethods cannot contain '*' alongside\n                                          other methods\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    allowOrigins:\n                                      description: |-\n                                        AllowOrigins indicates whether the response can be shared with requested\n                                        resource from the given `Origin`.\n\n                                        The `Origin` consists of a scheme and a host, with an optional port, and\n                                        takes the form `<scheme>://<host>(:<port>)`.\n\n                                        Valid values for scheme are: `http` and `https`.\n\n                                        Valid values for port are any integer between 1 and 65535 (the list of\n                                        available TCP/UDP ports). Note that, if not included, port `80` is\n                                        assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                        origins. This may affect origin matching.\n\n                                        The host part of the origin may contain the wildcard character `*`. These\n                                        wildcard characters behave as follows:\n\n                                        * `*` is a greedy match to the _left_, including any number of\n                                          DNS labels to the left of its position. This also means that\n                                          `*` will include any number of period `.` characters to the\n                                          left of its position.\n                                        * A wildcard by itself matches all hosts.\n\n                                        An origin value that includes _only_ the `*` character indicates requests\n                                        from all `Origin`s are allowed.\n\n                                        When the `AllowOrigins` field is configured with multiple origins, it\n                                        means the server supports clients from multiple origins. If the request\n                                        `Origin` matches the configured allowed origins, the gateway must return\n                                        the given `Origin` and sets value of the header\n                                        `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                        client.\n\n                                        The status code of a successful response to a \"preflight\" request is\n                                        always an OK status (i.e., 204 or 200).\n\n                                        If the request `Origin` does not match the configured allowed origins,\n                                        the gateway returns 204/200 response but doesn't set the relevant\n                                        cross-origin response headers. Alternatively, the gateway responds with\n                                        403 status to the \"preflight\" request is denied, coupled with omitting\n                                        the CORS headers. The cross-origin request fails on the client side.\n                                        Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                        Conversely, if the request `Origin` matches one of the configured\n                                        allowed origins, the gateway sets the response header\n                                        `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                        header provided by the client.\n\n                                        When config has the wildcard (\"*\") in allowOrigins, and the request\n                                        is not credentialed (e.g., it is a preflight request), the\n                                        `Access-Control-Allow-Origin` response header either contains the\n                                        wildcard as well or the Origin from the request.\n\n                                        When the request is credentialed, the gateway must not specify the `*`\n                                        wildcard in the `Access-Control-Allow-Origin` response header. When\n                                        also the `AllowCredentials` field is true and `AllowOrigins` field\n                                        specified with the `*` wildcard, the gateway must return a single origin\n                                        in the value of the `Access-Control-Allow-Origin` response header,\n                                        instead of specifying the `*` wildcard. The value of the header\n                                        `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                        the client.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                          encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                          scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                          URIs that include an authority MUST include a fully qualified domain name or\n                                          IP address as the host.\n                                        maxLength: 253\n                                        minLength: 1\n                                        pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                      x-kubernetes-validations:\n                                      - message: AllowOrigins cannot contain '*' alongside\n                                          other origins\n                                        rule: '!(''*'' in self && self.size() > 1)'\n                                    exposeHeaders:\n                                      description: |-\n                                        ExposeHeaders indicates which HTTP response headers can be exposed\n                                        to client-side scripts in response to a cross-origin request.\n\n                                        A CORS-safelisted response header is an HTTP header in a CORS response\n                                        that it is considered safe to expose to the client scripts.\n                                        The CORS-safelisted response headers include the following headers:\n                                        `Cache-Control`\n                                        `Content-Language`\n                                        `Content-Length`\n                                        `Content-Type`\n                                        `Expires`\n                                        `Last-Modified`\n                                        `Pragma`\n                                        (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                        The CORS-safelisted response headers are exposed to client by default.\n\n                                        When an HTTP header name is specified using the `ExposeHeaders` field,\n                                        this additional header will be exposed as part of the response to the\n                                        client.\n\n                                        Header names are not case-sensitive.\n\n                                        Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                        response header are separated by a comma (\",\").\n\n                                        A wildcard indicates that the responses with all HTTP headers are exposed\n                                        to clients. The `Access-Control-Expose-Headers` response header can only\n                                        use `*` wildcard as value when the request is not credentialed.\n\n                                        When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                        the request is credentialed, the gateway cannot use the `*` wildcard in\n                                        the `Access-Control-Expose-Headers` response header.\n\n                                        Support: Extended\n                                      items:\n                                        description: |-\n                                          HTTPHeaderName is the name of an HTTP header.\n\n                                          Valid values include:\n\n                                          * \"Authorization\"\n                                          * \"Set-Cookie\"\n\n                                          Invalid values include:\n\n                                            - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                              headers are not currently supported by this type.\n                                            - \"/invalid\" - \"/ \" is an invalid character\n                                        maxLength: 256\n                                        minLength: 1\n                                        pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                        type: string\n                                      maxItems: 64\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    maxAge:\n                                      default: 5\n                                      description: |-\n                                        MaxAge indicates the duration (in seconds) for the client to cache the\n                                        results of a \"preflight\" request.\n\n                                        The information provided by the `Access-Control-Allow-Methods` and\n                                        `Access-Control-Allow-Headers` response headers can be cached by the\n                                        client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                        The default value of `Access-Control-Max-Age` response header is 5\n                                        (seconds).\n\n                                        When the `MaxAge` field is unspecified, the gateway sets the response\n                                        header \"Access-Control-Max-Age: 5\" by default.\n                                      format: int32\n                                      minimum: 1\n                                      type: integer\n                                  type: object\n                                extensionRef:\n                                  description: |-\n                                    ExtensionRef is an optional, implementation-specific extension to the\n                                    \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                                    \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                                    extended filters.\n\n                                    This filter can be used multiple times within the same rule.\n\n                                    Support: Implementation-specific\n                                  properties:\n                                    group:\n                                      description: |-\n                                        Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                        When unspecified or empty string, core API group is inferred.\n                                      maxLength: 253\n                                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    kind:\n                                      description: Kind is kind of the referent. For\n                                        example \"HTTPRoute\" or \"Service\".\n                                      maxLength: 63\n                                      minLength: 1\n                                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                      type: string\n                                    name:\n                                      description: Name is the name of the referent.\n                                      maxLength: 253\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - group\n                                  - kind\n                                  - name\n                                  type: object\n                                requestHeaderModifier:\n                                  description: |-\n                                    RequestHeaderModifier defines a schema for a filter that modifies request\n                                    headers.\n\n                                    Support: Core\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                requestMirror:\n                                  description: |-\n                                    RequestMirror defines a schema for a filter that mirrors requests.\n                                    Requests are sent to the specified destination, but responses from\n                                    that destination are ignored.\n\n                                    This filter can be used multiple times within the same rule. Note that\n                                    not all implementations will be able to support mirroring to multiple\n                                    backends.\n\n                                    Support: Extended\n                                  properties:\n                                    backendRef:\n                                      description: |-\n                                        BackendRef references a resource where mirrored requests are sent.\n\n                                        Mirrored requests must be sent only to a single destination endpoint\n                                        within this BackendRef, irrespective of how many endpoints are present\n                                        within this BackendRef.\n\n                                        If the referent cannot be found, this BackendRef is invalid and must be\n                                        dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                        condition on the Route status is set to `status: False` and not configure\n                                        this backend in the underlying implementation.\n\n                                        If there is a cross-namespace reference to an *existing* object\n                                        that is not allowed by a ReferenceGrant, the controller must ensure the\n                                        \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                        with the \"RefNotPermitted\" reason and not configure this backend in the\n                                        underlying implementation.\n\n                                        In either error case, the Message of the `ResolvedRefs` Condition\n                                        should be used to provide more detail about the problem.\n\n                                        Support: Extended for Kubernetes Service\n\n                                        Support: Implementation-specific for any other resource\n                                      properties:\n                                        group:\n                                          default: \"\"\n                                          description: |-\n                                            Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                            When unspecified or empty string, core API group is inferred.\n                                          maxLength: 253\n                                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                          type: string\n                                        kind:\n                                          default: Service\n                                          description: |-\n                                            Kind is the Kubernetes resource kind of the referent. For example\n                                            \"Service\".\n\n                                            Defaults to \"Service\" when not specified.\n\n                                            ExternalName services can refer to CNAME DNS records that may live\n                                            outside of the cluster and as such are difficult to reason about in\n                                            terms of conformance. They also may not be safe to forward to (see\n                                            CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                            support ExternalName Services.\n\n                                            Support: Core (Services with a type other than ExternalName)\n\n                                            Support: Implementation-specific (Services with type ExternalName)\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                          type: string\n                                        name:\n                                          description: Name is the name of the referent.\n                                          maxLength: 253\n                                          minLength: 1\n                                          type: string\n                                        namespace:\n                                          description: |-\n                                            Namespace is the namespace of the backend. When unspecified, the local\n                                            namespace is inferred.\n\n                                            Note that when a namespace different than the local namespace is specified,\n                                            a ReferenceGrant object is required in the referent namespace to allow that\n                                            namespace's owner to accept the reference. See the ReferenceGrant\n                                            documentation for details.\n\n                                            Support: Core\n                                          maxLength: 63\n                                          minLength: 1\n                                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                          type: string\n                                        port:\n                                          description: |-\n                                            Port specifies the destination port number to use for this resource.\n                                            Port is required when the referent is a Kubernetes Service. In this\n                                            case, the port number is the service port number, not the target port.\n                                            For other resources, destination port might be derived from the referent\n                                            resource or this field.\n                                          format: int32\n                                          maximum: 65535\n                                          minimum: 1\n                                          type: integer\n                                      required:\n                                      - name\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: Must have port for Service reference\n                                        rule: '(size(self.group) == 0 && self.kind\n                                          == ''Service'') ? has(self.port) : true'\n                                    fraction:\n                                      description: |-\n                                        Fraction represents the fraction of requests that should be\n                                        mirrored to BackendRef.\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      properties:\n                                        denominator:\n                                          default: 100\n                                          format: int32\n                                          minimum: 1\n                                          type: integer\n                                        numerator:\n                                          format: int32\n                                          minimum: 0\n                                          type: integer\n                                      required:\n                                      - numerator\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: numerator must be less than or equal\n                                          to denominator\n                                        rule: self.numerator <= self.denominator\n                                    percent:\n                                      description: |-\n                                        Percent represents the percentage of requests that should be\n                                        mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                        requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                        Only one of Fraction or Percent may be specified. If neither field\n                                        is specified, 100% of requests will be mirrored.\n                                      format: int32\n                                      maximum: 100\n                                      minimum: 0\n                                      type: integer\n                                  required:\n                                  - backendRef\n                                  type: object\n                                  x-kubernetes-validations:\n                                  - message: Only one of percent or fraction may be\n                                      specified in HTTPRequestMirrorFilter\n                                    rule: '!(has(self.percent) && has(self.fraction))'\n                                requestRedirect:\n                                  description: |-\n                                    RequestRedirect defines a schema for a filter that responds to the\n                                    request with an HTTP redirection.\n\n                                    Support: Core\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the hostname to be used in the value of the `Location`\n                                        header in the response.\n                                        When empty, the hostname in the `Host` header of the request is used.\n\n                                        Support: Core\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines parameters used to modify the path of the incoming request.\n                                        The modified path is then used to construct the `Location` header. When\n                                        empty, the request path is used as-is.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                    port:\n                                      description: |-\n                                        Port is the port to be used in the value of the `Location`\n                                        header in the response.\n\n                                        If no port is specified, the redirect port MUST be derived using the\n                                        following rules:\n\n                                        * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                          port associated with the redirect scheme. Specifically \"http\" to port 80\n                                          and \"https\" to port 443. If the redirect scheme does not have a\n                                          well-known port, the listener port of the Gateway SHOULD be used.\n                                        * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                          Listener port.\n\n                                        Implementations SHOULD NOT add the port number in the 'Location'\n                                        header in the following cases:\n\n                                        * A Location header that will use HTTP (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 80.\n                                        * A Location header that will use HTTPS (whether that is determined via\n                                          the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                        Support: Extended\n                                      format: int32\n                                      maximum: 65535\n                                      minimum: 1\n                                      type: integer\n                                    scheme:\n                                      description: |-\n                                        Scheme is the scheme to be used in the value of the `Location` header in\n                                        the response. When empty, the scheme of the request is used.\n\n                                        Scheme redirects can affect the port of the redirect, for more information,\n                                        refer to the documentation for the port field of this filter.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Extended\n                                      enum:\n                                      - http\n                                      - https\n                                      type: string\n                                    statusCode:\n                                      default: 302\n                                      description: |-\n                                        StatusCode is the HTTP status code to be used in response.\n\n                                        Note that values may be added to this enum, implementations\n                                        must ensure that unknown values will not cause a crash.\n\n                                        Unknown values here must result in the implementation setting the\n                                        Accepted Condition for the Route to `status: False`, with a\n                                        Reason of `UnsupportedValue`.\n\n                                        Support: Core\n                                      enum:\n                                      - 301\n                                      - 302\n                                      - 303\n                                      - 307\n                                      - 308\n                                      type: integer\n                                  type: object\n                                responseHeaderModifier:\n                                  description: |-\n                                    ResponseHeaderModifier defines a schema for a filter that modifies response\n                                    headers.\n\n                                    Support: Extended\n                                  properties:\n                                    add:\n                                      description: |-\n                                        Add adds the given header(s) (name, value) to the request\n                                        before the action. It appends to any existing values associated\n                                        with the header name.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          add:\n                                          - name: \"my-header\"\n                                            value: \"bar,baz\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo,bar,baz\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                    remove:\n                                      description: |-\n                                        Remove the given header(s) from the HTTP request before the action. The\n                                        value of Remove is a list of HTTP header names. Note that the header\n                                        names are case-insensitive (see\n                                        https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header1: foo\n                                          my-header2: bar\n                                          my-header3: baz\n\n                                        Config:\n                                          remove: [\"my-header1\", \"my-header3\"]\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header2: bar\n                                      items:\n                                        type: string\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-type: set\n                                    set:\n                                      description: |-\n                                        Set overwrites the request with the given header (name, value)\n                                        before the action.\n\n                                        Input:\n                                          GET /foo HTTP/1.1\n                                          my-header: foo\n\n                                        Config:\n                                          set:\n                                          - name: \"my-header\"\n                                            value: \"bar\"\n\n                                        Output:\n                                          GET /foo HTTP/1.1\n                                          my-header: bar\n                                      items:\n                                        description: HTTPHeader represents an HTTP\n                                          Header name and value as defined by RFC\n                                          7230.\n                                        properties:\n                                          name:\n                                            description: |-\n                                              Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                              case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                              If multiple entries specify equivalent header names, the first entry with\n                                              an equivalent name MUST be considered for a match. Subsequent entries\n                                              with an equivalent header name MUST be ignored. Due to the\n                                              case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                              equivalent.\n                                            maxLength: 256\n                                            minLength: 1\n                                            pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                            type: string\n                                          value:\n                                            description: Value is the value of HTTP\n                                              Header to be matched.\n                                            maxLength: 4096\n                                            minLength: 1\n                                            type: string\n                                        required:\n                                        - name\n                                        - value\n                                        type: object\n                                      maxItems: 16\n                                      type: array\n                                      x-kubernetes-list-map-keys:\n                                      - name\n                                      x-kubernetes-list-type: map\n                                  type: object\n                                type:\n                                  description: |-\n                                    Type identifies the type of filter to apply. As with other API fields,\n                                    types are classified into three conformance levels:\n\n                                    - Core: Filter types and their corresponding configuration defined by\n                                      \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                      implementations must support core filters.\n\n                                    - Extended: Filter types and their corresponding configuration defined by\n                                      \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                      are encouraged to support extended filters.\n\n                                    - Implementation-specific: Filters that are defined and supported by\n                                      specific vendors.\n                                      In the future, filters showing convergence in behavior across multiple\n                                      implementations will be considered for inclusion in extended or core\n                                      conformance levels. Filter-specific configuration for such filters\n                                      is specified using the ExtensionRef field. `Type` should be set to\n                                      \"ExtensionRef\" for custom filters.\n\n                                    Implementers are encouraged to define custom implementation types to\n                                    extend the core API with implementation-specific behavior.\n\n                                    If a reference to a custom filter type cannot be resolved, the filter\n                                    MUST NOT be skipped. Instead, requests that would have been processed by\n                                    that filter MUST receive a HTTP error response.\n\n                                    Note that values may be added to this enum, implementations\n                                    must ensure that unknown values will not cause a crash.\n\n                                    Unknown values here must result in the implementation setting the\n                                    Accepted Condition for the Route to `status: False`, with a\n                                    Reason of `UnsupportedValue`.\n                                  enum:\n                                  - RequestHeaderModifier\n                                  - ResponseHeaderModifier\n                                  - RequestMirror\n                                  - RequestRedirect\n                                  - URLRewrite\n                                  - ExtensionRef\n                                  - CORS\n                                  type: string\n                                urlRewrite:\n                                  description: |-\n                                    URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                                    Support: Extended\n                                  properties:\n                                    hostname:\n                                      description: |-\n                                        Hostname is the value to be used to replace the Host header value during\n                                        forwarding.\n\n                                        Support: Extended\n                                      maxLength: 253\n                                      minLength: 1\n                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                      type: string\n                                    path:\n                                      description: |-\n                                        Path defines a path rewrite.\n\n                                        Support: Extended\n                                      properties:\n                                        replaceFullPath:\n                                          description: |-\n                                            ReplaceFullPath specifies the value with which to replace the full path\n                                            of a request during a rewrite or redirect.\n                                          maxLength: 1024\n                                          type: string\n                                        replacePrefixMatch:\n                                          description: |-\n                                            ReplacePrefixMatch specifies the value with which to replace the prefix\n                                            match of a request during a rewrite or redirect. For example, a request\n                                            to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                            of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                            Note that this matches the behavior of the PathPrefix match type. This\n                                            matches full path elements. A path element refers to the list of labels\n                                            in the path split by the `/` separator. When specified, a trailing `/` is\n                                            ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                            match the prefix `/abc`, but the path `/abcd` would not.\n\n                                            ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                            Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                            the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                            Request Path | Prefix Match | Replace Prefix | Modified Path\n                                          maxLength: 1024\n                                          type: string\n                                        type:\n                                          description: |-\n                                            Type defines the type of path modifier. Additional types may be\n                                            added in a future release of the API.\n\n                                            Note that values may be added to this enum, implementations\n                                            must ensure that unknown values will not cause a crash.\n\n                                            Unknown values here must result in the implementation setting the\n                                            Accepted Condition for the Route to `status: False`, with a\n                                            Reason of `UnsupportedValue`.\n                                          enum:\n                                          - ReplaceFullPath\n                                          - ReplacePrefixMatch\n                                          type: string\n                                      required:\n                                      - type\n                                      type: object\n                                      x-kubernetes-validations:\n                                      - message: replaceFullPath must be specified\n                                          when type is set to 'ReplaceFullPath'\n                                        rule: 'self.type == ''ReplaceFullPath'' ?\n                                          has(self.replaceFullPath) : true'\n                                      - message: type must be 'ReplaceFullPath' when\n                                          replaceFullPath is set\n                                        rule: 'has(self.replaceFullPath) ? self.type\n                                          == ''ReplaceFullPath'' : true'\n                                      - message: replacePrefixMatch must be specified\n                                          when type is set to 'ReplacePrefixMatch'\n                                        rule: 'self.type == ''ReplacePrefixMatch''\n                                          ? has(self.replacePrefixMatch) : true'\n                                      - message: type must be 'ReplacePrefixMatch'\n                                          when replacePrefixMatch is set\n                                        rule: 'has(self.replacePrefixMatch) ? self.type\n                                          == ''ReplacePrefixMatch'' : true'\n                                  type: object\n                              required:\n                              - type\n                              type: object\n                              x-kubernetes-validations:\n                              - message: filter.cors must be nil if the filter.type\n                                  is not CORS\n                                rule: '!(has(self.cors) && self.type != ''CORS'')'\n                              - message: filter.cors must be specified for CORS filter.type\n                                rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                              - message: filter.requestHeaderModifier must be nil\n                                  if the filter.type is not RequestHeaderModifier\n                                rule: '!(has(self.requestHeaderModifier) && self.type\n                                  != ''RequestHeaderModifier'')'\n                              - message: filter.requestHeaderModifier must be specified\n                                  for RequestHeaderModifier filter.type\n                                rule: '!(!has(self.requestHeaderModifier) && self.type\n                                  == ''RequestHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be nil\n                                  if the filter.type is not ResponseHeaderModifier\n                                rule: '!(has(self.responseHeaderModifier) && self.type\n                                  != ''ResponseHeaderModifier'')'\n                              - message: filter.responseHeaderModifier must be specified\n                                  for ResponseHeaderModifier filter.type\n                                rule: '!(!has(self.responseHeaderModifier) && self.type\n                                  == ''ResponseHeaderModifier'')'\n                              - message: filter.requestMirror must be nil if the filter.type\n                                  is not RequestMirror\n                                rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                              - message: filter.requestMirror must be specified for\n                                  RequestMirror filter.type\n                                rule: '!(!has(self.requestMirror) && self.type ==\n                                  ''RequestMirror'')'\n                              - message: filter.requestRedirect must be nil if the\n                                  filter.type is not RequestRedirect\n                                rule: '!(has(self.requestRedirect) && self.type !=\n                                  ''RequestRedirect'')'\n                              - message: filter.requestRedirect must be specified\n                                  for RequestRedirect filter.type\n                                rule: '!(!has(self.requestRedirect) && self.type ==\n                                  ''RequestRedirect'')'\n                              - message: filter.urlRewrite must be nil if the filter.type\n                                  is not URLRewrite\n                                rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                              - message: filter.urlRewrite must be specified for URLRewrite\n                                  filter.type\n                                rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                              - message: filter.extensionRef must be nil if the filter.type\n                                  is not ExtensionRef\n                                rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                              - message: filter.extensionRef must be specified for\n                                  ExtensionRef filter.type\n                                rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-type: atomic\n                            x-kubernetes-validations:\n                            - message: May specify either httpRouteFilterRequestRedirect\n                                or httpRouteFilterRequestRewrite, but not both\n                              rule: '!(self.exists(f, f.type == ''RequestRedirect'')\n                                && self.exists(f, f.type == ''URLRewrite''))'\n                            - message: RequestHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                                <= 1\n                            - message: ResponseHeaderModifier filter cannot be repeated\n                              rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                                <= 1\n                            - message: RequestRedirect filter cannot be repeated\n                              rule: self.filter(f, f.type == 'RequestRedirect').size()\n                                <= 1\n                            - message: URLRewrite filter cannot be repeated\n                              rule: self.filter(f, f.type == 'URLRewrite').size()\n                                <= 1\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    filters:\n                      description: |-\n                        Filters define the filters that are applied to requests that match\n                        this rule.\n\n                        Wherever possible, implementations SHOULD implement filters in the order\n                        they are specified.\n\n                        Implementations MAY choose to implement this ordering strictly, rejecting\n                        any combination or order of filters that cannot be supported. If implementations\n                        choose a strict interpretation of filter ordering, they MUST clearly document\n                        that behavior.\n\n                        To reject an invalid combination or order of filters, implementations SHOULD\n                        consider the Route Rules with this configuration invalid. If all Route Rules\n                        in a Route are invalid, the entire Route would be considered invalid. If only\n                        a portion of Route Rules are invalid, implementations MUST set the\n                        \"PartiallyInvalid\" condition for the Route.\n\n                        Conformance-levels at this level are defined based on the type of filter:\n\n                        - ALL core filters MUST be supported by all implementations.\n                        - Implementers are encouraged to support extended filters.\n                        - Implementation-specific custom filters have no API guarantees across\n                          implementations.\n\n                        Specifying the same filter multiple times is not supported unless explicitly\n                        indicated in the filter.\n\n                        All filters are expected to be compatible with each other except for the\n                        URLRewrite and RequestRedirect filters, which may not be combined. If an\n                        implementation cannot support other combinations of filters, they must clearly\n                        document that limitation. In cases where incompatible or unsupported\n                        filters are specified and cause the `Accepted` condition to be set to status\n                        `False`, implementations may use the `IncompatibleFilters` reason to specify\n                        this configuration error.\n\n                        Support: Core\n                      items:\n                        description: |-\n                          HTTPRouteFilter defines processing steps that must be completed during the\n                          request or response lifecycle. HTTPRouteFilters are meant as an extension\n                          point to express processing that may be done in Gateway implementations. Some\n                          examples include request or response modification, implementing\n                          authentication strategies, rate-limiting, and traffic shaping. API\n                          guarantee/conformance is defined based on the type of the filter.\n                        properties:\n                          cors:\n                            description: |-\n                              CORS defines a schema for a filter that responds to the\n                              cross-origin request based on HTTP response header.\n\n                              Support: Extended\n                            properties:\n                              allowCredentials:\n                                description: |-\n                                  AllowCredentials indicates whether the actual cross-origin request allows\n                                  to include credentials.\n\n                                  When set to true, the gateway will include the `Access-Control-Allow-Credentials`\n                                  response header with value true (case-sensitive).\n\n                                  When set to false or omitted the gateway will omit the header\n                                  `Access-Control-Allow-Credentials` entirely (this is the standard CORS\n                                  behavior).\n\n                                  Support: Extended\n                                type: boolean\n                              allowHeaders:\n                                description: |-\n                                  AllowHeaders indicates which HTTP request headers are supported for\n                                  accessing the requested resource.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Allow-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  When the `AllowHeaders` field is configured with one or more headers, the\n                                  gateway must return the `Access-Control-Allow-Headers` response header\n                                  which value is present in the `AllowHeaders` field.\n\n                                  If any header name in the `Access-Control-Request-Headers` request header\n                                  is not included in the list of header names specified by the response\n                                  header `Access-Control-Allow-Headers`, it will present an error on the\n                                  client side.\n\n                                  If any header name in the `Access-Control-Allow-Headers` response header\n                                  does not recognize by the client, it will also occur an error on the\n                                  client side.\n\n                                  A wildcard indicates that the requests with all HTTP headers are allowed.\n                                  If config contains the wildcard \"*\" in allowHeaders and the request is\n                                  not credentialed, the `Access-Control-Allow-Headers` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Headers from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Headers` response header. When\n                                  also the `AllowCredentials` field is true and `AllowHeaders` field\n                                  is specified with the `*` wildcard, the gateway must specify one or more\n                                  HTTP headers in the value of the `Access-Control-Allow-Headers` response\n                                  header. The value of the header `Access-Control-Allow-Headers` is same as\n                                  the `Access-Control-Request-Headers` header provided by the client. If\n                                  the header `Access-Control-Request-Headers` is not included in the\n                                  request, the gateway will omit the `Access-Control-Allow-Headers`\n                                  response header, instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowHeaders cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowMethods:\n                                description: |-\n                                  AllowMethods indicates which HTTP methods are supported for accessing the\n                                  requested resource.\n\n                                  Valid values are any method defined by RFC9110, along with the special\n                                  value `*`, which represents all HTTP methods are allowed.\n\n                                  Method names are case-sensitive, so these values are also case-sensitive.\n                                  (See https://www.rfc-editor.org/rfc/rfc2616#section-5.1.1)\n\n                                  Multiple method names in the value of the `Access-Control-Allow-Methods`\n                                  response header are separated by a comma (\",\").\n\n                                  A CORS-safelisted method is a method that is `GET`, `HEAD`, or `POST`.\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-method) The\n                                  CORS-safelisted methods are always allowed, regardless of whether they\n                                  are specified in the `AllowMethods` field.\n\n                                  When the `AllowMethods` field is configured with one or more methods, the\n                                  gateway must return the `Access-Control-Allow-Methods` response header\n                                  which value is present in the `AllowMethods` field.\n\n                                  If the HTTP method of the `Access-Control-Request-Method` request header\n                                  is not included in the list of methods specified by the response header\n                                  `Access-Control-Allow-Methods`, it will present an error on the client\n                                  side.\n\n                                  If config contains the wildcard \"*\" in allowMethods and the request is\n                                  not credentialed, the `Access-Control-Allow-Methods` response header\n                                  can either use the `*` wildcard or the value of\n                                  Access-Control-Request-Method from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Methods` response header. When\n                                  also the `AllowCredentials` field is true and `AllowMethods` field\n                                  specified with the `*` wildcard, the gateway must specify one HTTP method\n                                  in the value of the Access-Control-Allow-Methods response header. The\n                                  value of the header `Access-Control-Allow-Methods` is same as the\n                                  `Access-Control-Request-Method` header provided by the client. If the\n                                  header `Access-Control-Request-Method` is not included in the request,\n                                  the gateway will omit the `Access-Control-Allow-Methods` response header,\n                                  instead of specifying the `*` wildcard.\n\n                                  Support: Extended\n                                items:\n                                  enum:\n                                  - GET\n                                  - HEAD\n                                  - POST\n                                  - PUT\n                                  - DELETE\n                                  - CONNECT\n                                  - OPTIONS\n                                  - TRACE\n                                  - PATCH\n                                  - '*'\n                                  type: string\n                                maxItems: 9\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowMethods cannot contain '*' alongside\n                                    other methods\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              allowOrigins:\n                                description: |-\n                                  AllowOrigins indicates whether the response can be shared with requested\n                                  resource from the given `Origin`.\n\n                                  The `Origin` consists of a scheme and a host, with an optional port, and\n                                  takes the form `<scheme>://<host>(:<port>)`.\n\n                                  Valid values for scheme are: `http` and `https`.\n\n                                  Valid values for port are any integer between 1 and 65535 (the list of\n                                  available TCP/UDP ports). Note that, if not included, port `80` is\n                                  assumed for `http` scheme origins, and port `443` is assumed for `https`\n                                  origins. This may affect origin matching.\n\n                                  The host part of the origin may contain the wildcard character `*`. These\n                                  wildcard characters behave as follows:\n\n                                  * `*` is a greedy match to the _left_, including any number of\n                                    DNS labels to the left of its position. This also means that\n                                    `*` will include any number of period `.` characters to the\n                                    left of its position.\n                                  * A wildcard by itself matches all hosts.\n\n                                  An origin value that includes _only_ the `*` character indicates requests\n                                  from all `Origin`s are allowed.\n\n                                  When the `AllowOrigins` field is configured with multiple origins, it\n                                  means the server supports clients from multiple origins. If the request\n                                  `Origin` matches the configured allowed origins, the gateway must return\n                                  the given `Origin` and sets value of the header\n                                  `Access-Control-Allow-Origin` same as the `Origin` header provided by the\n                                  client.\n\n                                  The status code of a successful response to a \"preflight\" request is\n                                  always an OK status (i.e., 204 or 200).\n\n                                  If the request `Origin` does not match the configured allowed origins,\n                                  the gateway returns 204/200 response but doesn't set the relevant\n                                  cross-origin response headers. Alternatively, the gateway responds with\n                                  403 status to the \"preflight\" request is denied, coupled with omitting\n                                  the CORS headers. The cross-origin request fails on the client side.\n                                  Therefore, the client doesn't attempt the actual cross-origin request.\n\n                                  Conversely, if the request `Origin` matches one of the configured\n                                  allowed origins, the gateway sets the response header\n                                  `Access-Control-Allow-Origin` to the same value as the `Origin`\n                                  header provided by the client.\n\n                                  When config has the wildcard (\"*\") in allowOrigins, and the request\n                                  is not credentialed (e.g., it is a preflight request), the\n                                  `Access-Control-Allow-Origin` response header either contains the\n                                  wildcard as well or the Origin from the request.\n\n                                  When the request is credentialed, the gateway must not specify the `*`\n                                  wildcard in the `Access-Control-Allow-Origin` response header. When\n                                  also the `AllowCredentials` field is true and `AllowOrigins` field\n                                  specified with the `*` wildcard, the gateway must return a single origin\n                                  in the value of the `Access-Control-Allow-Origin` response header,\n                                  instead of specifying the `*` wildcard. The value of the header\n                                  `Access-Control-Allow-Origin` is same as the `Origin` header provided by\n                                  the client.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    The CORSOrigin MUST NOT be a relative URI, and it MUST follow the URI syntax and\n                                    encoding rules specified in RFC3986.  The CORSOrigin MUST include both a\n                                    scheme (e.g., \"http\" or \"spiffe\") and a scheme-specific-part, or it should be a single '*' character.\n                                    URIs that include an authority MUST include a fully qualified domain name or\n                                    IP address as the host.\n                                  maxLength: 253\n                                  minLength: 1\n                                  pattern: (^\\*$)|(^([a-zA-Z][a-zA-Z0-9+\\-.]+):\\/\\/([^:/?#]+)(:([0-9]{1,5}))?$)\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                                x-kubernetes-validations:\n                                - message: AllowOrigins cannot contain '*' alongside\n                                    other origins\n                                  rule: '!(''*'' in self && self.size() > 1)'\n                              exposeHeaders:\n                                description: |-\n                                  ExposeHeaders indicates which HTTP response headers can be exposed\n                                  to client-side scripts in response to a cross-origin request.\n\n                                  A CORS-safelisted response header is an HTTP header in a CORS response\n                                  that it is considered safe to expose to the client scripts.\n                                  The CORS-safelisted response headers include the following headers:\n                                  `Cache-Control`\n                                  `Content-Language`\n                                  `Content-Length`\n                                  `Content-Type`\n                                  `Expires`\n                                  `Last-Modified`\n                                  `Pragma`\n                                  (See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name)\n                                  The CORS-safelisted response headers are exposed to client by default.\n\n                                  When an HTTP header name is specified using the `ExposeHeaders` field,\n                                  this additional header will be exposed as part of the response to the\n                                  client.\n\n                                  Header names are not case-sensitive.\n\n                                  Multiple header names in the value of the `Access-Control-Expose-Headers`\n                                  response header are separated by a comma (\",\").\n\n                                  A wildcard indicates that the responses with all HTTP headers are exposed\n                                  to clients. The `Access-Control-Expose-Headers` response header can only\n                                  use `*` wildcard as value when the request is not credentialed.\n\n                                  When the `exposeHeaders` config field contains the \"*\" wildcard and\n                                  the request is credentialed, the gateway cannot use the `*` wildcard in\n                                  the `Access-Control-Expose-Headers` response header.\n\n                                  Support: Extended\n                                items:\n                                  description: |-\n                                    HTTPHeaderName is the name of an HTTP header.\n\n                                    Valid values include:\n\n                                    * \"Authorization\"\n                                    * \"Set-Cookie\"\n\n                                    Invalid values include:\n\n                                      - \":method\" - \":\" is an invalid character. This means that HTTP/2 pseudo\n                                        headers are not currently supported by this type.\n                                      - \"/invalid\" - \"/ \" is an invalid character\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                maxItems: 64\n                                type: array\n                                x-kubernetes-list-type: set\n                              maxAge:\n                                default: 5\n                                description: |-\n                                  MaxAge indicates the duration (in seconds) for the client to cache the\n                                  results of a \"preflight\" request.\n\n                                  The information provided by the `Access-Control-Allow-Methods` and\n                                  `Access-Control-Allow-Headers` response headers can be cached by the\n                                  client until the time specified by `Access-Control-Max-Age` elapses.\n\n                                  The default value of `Access-Control-Max-Age` response header is 5\n                                  (seconds).\n\n                                  When the `MaxAge` field is unspecified, the gateway sets the response\n                                  header \"Access-Control-Max-Age: 5\" by default.\n                                format: int32\n                                minimum: 1\n                                type: integer\n                            type: object\n                          extensionRef:\n                            description: |-\n                              ExtensionRef is an optional, implementation-specific extension to the\n                              \"filter\" behavior.  For example, resource \"myroutefilter\" in group\n                              \"networking.example.net\"). ExtensionRef MUST NOT be used for core and\n                              extended filters.\n\n                              This filter can be used multiple times within the same rule.\n\n                              Support: Implementation-specific\n                            properties:\n                              group:\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is kind of the referent. For example\n                                  \"HTTPRoute\" or \"Service\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                            required:\n                            - group\n                            - kind\n                            - name\n                            type: object\n                          requestHeaderModifier:\n                            description: |-\n                              RequestHeaderModifier defines a schema for a filter that modifies request\n                              headers.\n\n                              Support: Core\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          requestMirror:\n                            description: |-\n                              RequestMirror defines a schema for a filter that mirrors requests.\n                              Requests are sent to the specified destination, but responses from\n                              that destination are ignored.\n\n                              This filter can be used multiple times within the same rule. Note that\n                              not all implementations will be able to support mirroring to multiple\n                              backends.\n\n                              Support: Extended\n                            properties:\n                              backendRef:\n                                description: |-\n                                  BackendRef references a resource where mirrored requests are sent.\n\n                                  Mirrored requests must be sent only to a single destination endpoint\n                                  within this BackendRef, irrespective of how many endpoints are present\n                                  within this BackendRef.\n\n                                  If the referent cannot be found, this BackendRef is invalid and must be\n                                  dropped from the Gateway. The controller must ensure the \"ResolvedRefs\"\n                                  condition on the Route status is set to `status: False` and not configure\n                                  this backend in the underlying implementation.\n\n                                  If there is a cross-namespace reference to an *existing* object\n                                  that is not allowed by a ReferenceGrant, the controller must ensure the\n                                  \"ResolvedRefs\"  condition on the Route is set to `status: False`,\n                                  with the \"RefNotPermitted\" reason and not configure this backend in the\n                                  underlying implementation.\n\n                                  In either error case, the Message of the `ResolvedRefs` Condition\n                                  should be used to provide more detail about the problem.\n\n                                  Support: Extended for Kubernetes Service\n\n                                  Support: Implementation-specific for any other resource\n                                properties:\n                                  group:\n                                    default: \"\"\n                                    description: |-\n                                      Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                      When unspecified or empty string, core API group is inferred.\n                                    maxLength: 253\n                                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                    type: string\n                                  kind:\n                                    default: Service\n                                    description: |-\n                                      Kind is the Kubernetes resource kind of the referent. For example\n                                      \"Service\".\n\n                                      Defaults to \"Service\" when not specified.\n\n                                      ExternalName services can refer to CNAME DNS records that may live\n                                      outside of the cluster and as such are difficult to reason about in\n                                      terms of conformance. They also may not be safe to forward to (see\n                                      CVE-2021-25740 for more information). Implementations SHOULD NOT\n                                      support ExternalName Services.\n\n                                      Support: Core (Services with a type other than ExternalName)\n\n                                      Support: Implementation-specific (Services with type ExternalName)\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                    type: string\n                                  name:\n                                    description: Name is the name of the referent.\n                                    maxLength: 253\n                                    minLength: 1\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of the backend. When unspecified, the local\n                                      namespace is inferred.\n\n                                      Note that when a namespace different than the local namespace is specified,\n                                      a ReferenceGrant object is required in the referent namespace to allow that\n                                      namespace's owner to accept the reference. See the ReferenceGrant\n                                      documentation for details.\n\n                                      Support: Core\n                                    maxLength: 63\n                                    minLength: 1\n                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                    type: string\n                                  port:\n                                    description: |-\n                                      Port specifies the destination port number to use for this resource.\n                                      Port is required when the referent is a Kubernetes Service. In this\n                                      case, the port number is the service port number, not the target port.\n                                      For other resources, destination port might be derived from the referent\n                                      resource or this field.\n                                    format: int32\n                                    maximum: 65535\n                                    minimum: 1\n                                    type: integer\n                                required:\n                                - name\n                                type: object\n                                x-kubernetes-validations:\n                                - message: Must have port for Service reference\n                                  rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                                    ? has(self.port) : true'\n                              fraction:\n                                description: |-\n                                  Fraction represents the fraction of requests that should be\n                                  mirrored to BackendRef.\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                properties:\n                                  denominator:\n                                    default: 100\n                                    format: int32\n                                    minimum: 1\n                                    type: integer\n                                  numerator:\n                                    format: int32\n                                    minimum: 0\n                                    type: integer\n                                required:\n                                - numerator\n                                type: object\n                                x-kubernetes-validations:\n                                - message: numerator must be less than or equal to\n                                    denominator\n                                  rule: self.numerator <= self.denominator\n                              percent:\n                                description: |-\n                                  Percent represents the percentage of requests that should be\n                                  mirrored to BackendRef. Its minimum value is 0 (indicating 0% of\n                                  requests) and its maximum value is 100 (indicating 100% of requests).\n\n                                  Only one of Fraction or Percent may be specified. If neither field\n                                  is specified, 100% of requests will be mirrored.\n                                format: int32\n                                maximum: 100\n                                minimum: 0\n                                type: integer\n                            required:\n                            - backendRef\n                            type: object\n                            x-kubernetes-validations:\n                            - message: Only one of percent or fraction may be specified\n                                in HTTPRequestMirrorFilter\n                              rule: '!(has(self.percent) && has(self.fraction))'\n                          requestRedirect:\n                            description: |-\n                              RequestRedirect defines a schema for a filter that responds to the\n                              request with an HTTP redirection.\n\n                              Support: Core\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the hostname to be used in the value of the `Location`\n                                  header in the response.\n                                  When empty, the hostname in the `Host` header of the request is used.\n\n                                  Support: Core\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines parameters used to modify the path of the incoming request.\n                                  The modified path is then used to construct the `Location` header. When\n                                  empty, the request path is used as-is.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                              port:\n                                description: |-\n                                  Port is the port to be used in the value of the `Location`\n                                  header in the response.\n\n                                  If no port is specified, the redirect port MUST be derived using the\n                                  following rules:\n\n                                  * If redirect scheme is not-empty, the redirect port MUST be the well-known\n                                    port associated with the redirect scheme. Specifically \"http\" to port 80\n                                    and \"https\" to port 443. If the redirect scheme does not have a\n                                    well-known port, the listener port of the Gateway SHOULD be used.\n                                  * If redirect scheme is empty, the redirect port MUST be the Gateway\n                                    Listener port.\n\n                                  Implementations SHOULD NOT add the port number in the 'Location'\n                                  header in the following cases:\n\n                                  * A Location header that will use HTTP (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 80.\n                                  * A Location header that will use HTTPS (whether that is determined via\n                                    the Listener protocol or the Scheme field) _and_ use port 443.\n\n                                  Support: Extended\n                                format: int32\n                                maximum: 65535\n                                minimum: 1\n                                type: integer\n                              scheme:\n                                description: |-\n                                  Scheme is the scheme to be used in the value of the `Location` header in\n                                  the response. When empty, the scheme of the request is used.\n\n                                  Scheme redirects can affect the port of the redirect, for more information,\n                                  refer to the documentation for the port field of this filter.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Extended\n                                enum:\n                                - http\n                                - https\n                                type: string\n                              statusCode:\n                                default: 302\n                                description: |-\n                                  StatusCode is the HTTP status code to be used in response.\n\n                                  Note that values may be added to this enum, implementations\n                                  must ensure that unknown values will not cause a crash.\n\n                                  Unknown values here must result in the implementation setting the\n                                  Accepted Condition for the Route to `status: False`, with a\n                                  Reason of `UnsupportedValue`.\n\n                                  Support: Core\n                                enum:\n                                - 301\n                                - 302\n                                - 303\n                                - 307\n                                - 308\n                                type: integer\n                            type: object\n                          responseHeaderModifier:\n                            description: |-\n                              ResponseHeaderModifier defines a schema for a filter that modifies response\n                              headers.\n\n                              Support: Extended\n                            properties:\n                              add:\n                                description: |-\n                                  Add adds the given header(s) (name, value) to the request\n                                  before the action. It appends to any existing values associated\n                                  with the header name.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    add:\n                                    - name: \"my-header\"\n                                      value: \"bar,baz\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo,bar,baz\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                              remove:\n                                description: |-\n                                  Remove the given header(s) from the HTTP request before the action. The\n                                  value of Remove is a list of HTTP header names. Note that the header\n                                  names are case-insensitive (see\n                                  https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header1: foo\n                                    my-header2: bar\n                                    my-header3: baz\n\n                                  Config:\n                                    remove: [\"my-header1\", \"my-header3\"]\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header2: bar\n                                items:\n                                  type: string\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-type: set\n                              set:\n                                description: |-\n                                  Set overwrites the request with the given header (name, value)\n                                  before the action.\n\n                                  Input:\n                                    GET /foo HTTP/1.1\n                                    my-header: foo\n\n                                  Config:\n                                    set:\n                                    - name: \"my-header\"\n                                      value: \"bar\"\n\n                                  Output:\n                                    GET /foo HTTP/1.1\n                                    my-header: bar\n                                items:\n                                  description: HTTPHeader represents an HTTP Header\n                                    name and value as defined by RFC 7230.\n                                  properties:\n                                    name:\n                                      description: |-\n                                        Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                        case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                        If multiple entries specify equivalent header names, the first entry with\n                                        an equivalent name MUST be considered for a match. Subsequent entries\n                                        with an equivalent header name MUST be ignored. Due to the\n                                        case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                        equivalent.\n                                      maxLength: 256\n                                      minLength: 1\n                                      pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                      type: string\n                                    value:\n                                      description: Value is the value of HTTP Header\n                                        to be matched.\n                                      maxLength: 4096\n                                      minLength: 1\n                                      type: string\n                                  required:\n                                  - name\n                                  - value\n                                  type: object\n                                maxItems: 16\n                                type: array\n                                x-kubernetes-list-map-keys:\n                                - name\n                                x-kubernetes-list-type: map\n                            type: object\n                          type:\n                            description: |-\n                              Type identifies the type of filter to apply. As with other API fields,\n                              types are classified into three conformance levels:\n\n                              - Core: Filter types and their corresponding configuration defined by\n                                \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All\n                                implementations must support core filters.\n\n                              - Extended: Filter types and their corresponding configuration defined by\n                                \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers\n                                are encouraged to support extended filters.\n\n                              - Implementation-specific: Filters that are defined and supported by\n                                specific vendors.\n                                In the future, filters showing convergence in behavior across multiple\n                                implementations will be considered for inclusion in extended or core\n                                conformance levels. Filter-specific configuration for such filters\n                                is specified using the ExtensionRef field. `Type` should be set to\n                                \"ExtensionRef\" for custom filters.\n\n                              Implementers are encouraged to define custom implementation types to\n                              extend the core API with implementation-specific behavior.\n\n                              If a reference to a custom filter type cannot be resolved, the filter\n                              MUST NOT be skipped. Instead, requests that would have been processed by\n                              that filter MUST receive a HTTP error response.\n\n                              Note that values may be added to this enum, implementations\n                              must ensure that unknown values will not cause a crash.\n\n                              Unknown values here must result in the implementation setting the\n                              Accepted Condition for the Route to `status: False`, with a\n                              Reason of `UnsupportedValue`.\n                            enum:\n                            - RequestHeaderModifier\n                            - ResponseHeaderModifier\n                            - RequestMirror\n                            - RequestRedirect\n                            - URLRewrite\n                            - ExtensionRef\n                            - CORS\n                            type: string\n                          urlRewrite:\n                            description: |-\n                              URLRewrite defines a schema for a filter that modifies a request during forwarding.\n\n                              Support: Extended\n                            properties:\n                              hostname:\n                                description: |-\n                                  Hostname is the value to be used to replace the Host header value during\n                                  forwarding.\n\n                                  Support: Extended\n                                maxLength: 253\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              path:\n                                description: |-\n                                  Path defines a path rewrite.\n\n                                  Support: Extended\n                                properties:\n                                  replaceFullPath:\n                                    description: |-\n                                      ReplaceFullPath specifies the value with which to replace the full path\n                                      of a request during a rewrite or redirect.\n                                    maxLength: 1024\n                                    type: string\n                                  replacePrefixMatch:\n                                    description: |-\n                                      ReplacePrefixMatch specifies the value with which to replace the prefix\n                                      match of a request during a rewrite or redirect. For example, a request\n                                      to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch\n                                      of \"/xyz\" would be modified to \"/xyz/bar\".\n\n                                      Note that this matches the behavior of the PathPrefix match type. This\n                                      matches full path elements. A path element refers to the list of labels\n                                      in the path split by the `/` separator. When specified, a trailing `/` is\n                                      ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all\n                                      match the prefix `/abc`, but the path `/abcd` would not.\n\n                                      ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch.\n                                      Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in\n                                      the implementation setting the Accepted Condition for the Route to `status: False`.\n\n                                      Request Path | Prefix Match | Replace Prefix | Modified Path\n                                    maxLength: 1024\n                                    type: string\n                                  type:\n                                    description: |-\n                                      Type defines the type of path modifier. Additional types may be\n                                      added in a future release of the API.\n\n                                      Note that values may be added to this enum, implementations\n                                      must ensure that unknown values will not cause a crash.\n\n                                      Unknown values here must result in the implementation setting the\n                                      Accepted Condition for the Route to `status: False`, with a\n                                      Reason of `UnsupportedValue`.\n                                    enum:\n                                    - ReplaceFullPath\n                                    - ReplacePrefixMatch\n                                    type: string\n                                required:\n                                - type\n                                type: object\n                                x-kubernetes-validations:\n                                - message: replaceFullPath must be specified when\n                                    type is set to 'ReplaceFullPath'\n                                  rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath)\n                                    : true'\n                                - message: type must be 'ReplaceFullPath' when replaceFullPath\n                                    is set\n                                  rule: 'has(self.replaceFullPath) ? self.type ==\n                                    ''ReplaceFullPath'' : true'\n                                - message: replacePrefixMatch must be specified when\n                                    type is set to 'ReplacePrefixMatch'\n                                  rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch)\n                                    : true'\n                                - message: type must be 'ReplacePrefixMatch' when\n                                    replacePrefixMatch is set\n                                  rule: 'has(self.replacePrefixMatch) ? self.type\n                                    == ''ReplacePrefixMatch'' : true'\n                            type: object\n                        required:\n                        - type\n                        type: object\n                        x-kubernetes-validations:\n                        - message: filter.cors must be nil if the filter.type is not\n                            CORS\n                          rule: '!(has(self.cors) && self.type != ''CORS'')'\n                        - message: filter.cors must be specified for CORS filter.type\n                          rule: '!(!has(self.cors) && self.type == ''CORS'')'\n                        - message: filter.requestHeaderModifier must be nil if the\n                            filter.type is not RequestHeaderModifier\n                          rule: '!(has(self.requestHeaderModifier) && self.type !=\n                            ''RequestHeaderModifier'')'\n                        - message: filter.requestHeaderModifier must be specified\n                            for RequestHeaderModifier filter.type\n                          rule: '!(!has(self.requestHeaderModifier) && self.type ==\n                            ''RequestHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be nil if the\n                            filter.type is not ResponseHeaderModifier\n                          rule: '!(has(self.responseHeaderModifier) && self.type !=\n                            ''ResponseHeaderModifier'')'\n                        - message: filter.responseHeaderModifier must be specified\n                            for ResponseHeaderModifier filter.type\n                          rule: '!(!has(self.responseHeaderModifier) && self.type\n                            == ''ResponseHeaderModifier'')'\n                        - message: filter.requestMirror must be nil if the filter.type\n                            is not RequestMirror\n                          rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'\n                        - message: filter.requestMirror must be specified for RequestMirror\n                            filter.type\n                          rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'\n                        - message: filter.requestRedirect must be nil if the filter.type\n                            is not RequestRedirect\n                          rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')'\n                        - message: filter.requestRedirect must be specified for RequestRedirect\n                            filter.type\n                          rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')'\n                        - message: filter.urlRewrite must be nil if the filter.type\n                            is not URLRewrite\n                          rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')'\n                        - message: filter.urlRewrite must be specified for URLRewrite\n                            filter.type\n                          rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')'\n                        - message: filter.extensionRef must be nil if the filter.type\n                            is not ExtensionRef\n                          rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'\n                        - message: filter.extensionRef must be specified for ExtensionRef\n                            filter.type\n                          rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'\n                      maxItems: 16\n                      type: array\n                      x-kubernetes-list-type: atomic\n                      x-kubernetes-validations:\n                      - message: May specify either httpRouteFilterRequestRedirect\n                          or httpRouteFilterRequestRewrite, but not both\n                        rule: '!(self.exists(f, f.type == ''RequestRedirect'') &&\n                          self.exists(f, f.type == ''URLRewrite''))'\n                      - message: RequestHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestHeaderModifier').size()\n                          <= 1\n                      - message: ResponseHeaderModifier filter cannot be repeated\n                        rule: self.filter(f, f.type == 'ResponseHeaderModifier').size()\n                          <= 1\n                      - message: RequestRedirect filter cannot be repeated\n                        rule: self.filter(f, f.type == 'RequestRedirect').size() <=\n                          1\n                      - message: URLRewrite filter cannot be repeated\n                        rule: self.filter(f, f.type == 'URLRewrite').size() <= 1\n                    matches:\n                      default:\n                      - path:\n                          type: PathPrefix\n                          value: /\n                      description: |-\n                        Matches define conditions used for matching the rule against incoming\n                        HTTP requests. Each match is independent, i.e. this rule will be matched\n                        if **any** one of the matches is satisfied.\n\n                        For example, take the following matches configuration:\n\n                        ```\n                        matches:\n                        - path:\n                            value: \"/foo\"\n                          headers:\n                          - name: \"version\"\n                            value: \"v2\"\n                        - path:\n                            value: \"/v2/foo\"\n                        ```\n\n                        For a request to match against this rule, a request must satisfy\n                        EITHER of the two conditions:\n\n                        - path prefixed with `/foo` AND contains the header `version: v2`\n                        - path prefix of `/v2/foo`\n\n                        See the documentation for HTTPRouteMatch on how to specify multiple\n                        match conditions that should be ANDed together.\n\n                        If no matches are specified, the default is a prefix\n                        path match on \"/\", which has the effect of matching every\n                        HTTP request.\n\n                        Proxy or Load Balancer routing configuration generated from HTTPRoutes\n                        MUST prioritize matches based on the following criteria, continuing on\n                        ties. Across all rules specified on applicable Routes, precedence must be\n                        given to the match having:\n\n                        * \"Exact\" path match.\n                        * \"Prefix\" path match with largest number of characters.\n                        * Method match.\n                        * Largest number of header matches.\n                        * Largest number of query param matches.\n\n                        Note: The precedence of RegularExpression path matches are implementation-specific.\n\n                        If ties still exist across multiple Routes, matching precedence MUST be\n                        determined in order of the following criteria, continuing on ties:\n\n                        * The oldest Route based on creation timestamp.\n                        * The Route appearing first in alphabetical order by\n                          \"{namespace}/{name}\".\n\n                        If ties still exist within an HTTPRoute, matching precedence MUST be granted\n                        to the FIRST matching rule (in list order) with a match meeting the above\n                        criteria.\n\n                        When no rules matching a request have been successfully attached to the\n                        parent a request is coming from, a HTTP 404 status code MUST be returned.\n                      items:\n                        description: \"HTTPRouteMatch defines the predicate used to\n                          match requests to a given\\naction. Multiple match types\n                          are ANDed together, i.e. the match will\\nevaluate to true\n                          only if all conditions are satisfied.\\n\\nFor example, the\n                          match below will match a HTTP request only if its path\\nstarts\n                          with `/foo` AND it contains the `version: v1` header:\\n\\n```\\nmatch:\\n\\n\\tpath:\\n\\t\n                          \\ value: \\\"/foo\\\"\\n\\theaders:\\n\\t- name: \\\"version\\\"\\n\\t\n                          \\ value \\\"v1\\\"\\n\\n```\"\n                        properties:\n                          headers:\n                            description: |-\n                              Headers specifies HTTP request header matchers. Multiple match values are\n                              ANDed together, meaning, a request must match all the specified headers\n                              to select the route.\n                            items:\n                              description: |-\n                                HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request\n                                headers.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP Header to be matched. Name matching MUST be\n                                    case-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\n                                    If multiple entries specify equivalent header names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent header name MUST be ignored. Due to the\n                                    case-insensitivity of header names, \"foo\" and \"Foo\" are considered\n                                    equivalent.\n\n                                    When a header is repeated in an HTTP request, it is\n                                    implementation-specific behavior as to how this is represented.\n                                    Generally, proxies should follow the guidance from the RFC:\n                                    https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding\n                                    processing a repeated header, with special handling for \"Set-Cookie\".\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the header.\n\n                                    Support: Core (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression HeaderMatchType has implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other dialects\n                                    of regular expressions. Please read the implementation's documentation to\n                                    determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of HTTP Header to\n                                    be matched.\n                                  maxLength: 4096\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                          method:\n                            description: |-\n                              Method specifies HTTP method matcher.\n                              When specified, this route will be matched only if the request has the\n                              specified method.\n\n                              Support: Extended\n                            enum:\n                            - GET\n                            - HEAD\n                            - POST\n                            - PUT\n                            - DELETE\n                            - CONNECT\n                            - OPTIONS\n                            - TRACE\n                            - PATCH\n                            type: string\n                          path:\n                            default:\n                              type: PathPrefix\n                              value: /\n                            description: |-\n                              Path specifies a HTTP request path matcher. If this field is not\n                              specified, a default prefix match on the \"/\" path is provided.\n                            properties:\n                              type:\n                                default: PathPrefix\n                                description: |-\n                                  Type specifies how to match against the path Value.\n\n                                  Support: Core (Exact, PathPrefix)\n\n                                  Support: Implementation-specific (RegularExpression)\n                                enum:\n                                - Exact\n                                - PathPrefix\n                                - RegularExpression\n                                type: string\n                              value:\n                                default: /\n                                description: Value of the HTTP path to match against.\n                                maxLength: 1024\n                                type: string\n                            type: object\n                            x-kubernetes-validations:\n                            - message: value must be an absolute path and start with\n                                '/' when type one of ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'')\n                                : true'\n                            - message: must not contain '//' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'')\n                                : true'\n                            - message: must not contain '/./' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'')\n                                : true'\n                            - message: must not contain '/../' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'')\n                                : true'\n                            - message: must not contain '%2f' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'')\n                                : true'\n                            - message: must not contain '%2F' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'')\n                                : true'\n                            - message: must not contain '#' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'')\n                                : true'\n                            - message: must not end with '/..' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'')\n                                : true'\n                            - message: must not end with '/.' when type one of ['Exact',\n                                'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'')\n                                : true'\n                            - message: type must be one of ['Exact', 'PathPrefix',\n                                'RegularExpression']\n                              rule: self.type in ['Exact','PathPrefix'] || self.type\n                                == 'RegularExpression'\n                            - message: must only contain valid characters (matching\n                                ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$)\n                                for types ['Exact', 'PathPrefix']\n                              rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r\"\"\"^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$\"\"\")\n                                : true'\n                          queryParams:\n                            description: |-\n                              QueryParams specifies HTTP query parameter matchers. Multiple match\n                              values are ANDed together, meaning, a request must match all the\n                              specified query parameters to select the route.\n\n                              Support: Extended\n                            items:\n                              description: |-\n                                HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP\n                                query parameters.\n                              properties:\n                                name:\n                                  description: |-\n                                    Name is the name of the HTTP query param to be matched. This must be an\n                                    exact string match. (See\n                                    https://tools.ietf.org/html/rfc7230#section-2.7.3).\n\n                                    If multiple entries specify equivalent query param names, only the first\n                                    entry with an equivalent name MUST be considered for a match. Subsequent\n                                    entries with an equivalent query param name MUST be ignored.\n\n                                    If a query param is repeated in an HTTP request, the behavior is\n                                    purposely left undefined, since different data planes have different\n                                    capabilities. However, it is *recommended* that implementations should\n                                    match against the first value of the param if the data plane supports it,\n                                    as this behavior is expected in other load balancing contexts outside of\n                                    the Gateway API.\n\n                                    Users SHOULD NOT route traffic based on repeated query params to guard\n                                    themselves against potential differences in the implementations.\n                                  maxLength: 256\n                                  minLength: 1\n                                  pattern: ^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$\n                                  type: string\n                                type:\n                                  default: Exact\n                                  description: |-\n                                    Type specifies how to match against the value of the query parameter.\n\n                                    Support: Extended (Exact)\n\n                                    Support: Implementation-specific (RegularExpression)\n\n                                    Since RegularExpression QueryParamMatchType has Implementation-specific\n                                    conformance, implementations can support POSIX, PCRE or any other\n                                    dialects of regular expressions. Please read the implementation's\n                                    documentation to determine the supported dialect.\n                                  enum:\n                                  - Exact\n                                  - RegularExpression\n                                  type: string\n                                value:\n                                  description: Value is the value of HTTP query param\n                                    to be matched.\n                                  maxLength: 1024\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - name\n                              - value\n                              type: object\n                            maxItems: 16\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - name\n                            x-kubernetes-list-type: map\n                        type: object\n                      maxItems: 64\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: |-\n                        Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\n                        Support: Extended\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    timeouts:\n                      description: |-\n                        Timeouts defines the timeouts that can be configured for an HTTP request.\n\n                        Support: Extended\n                      properties:\n                        backendRequest:\n                          description: |-\n                            BackendRequest specifies a timeout for an individual request from the gateway\n                            to a backend. This covers the time from when the request first starts being\n                            sent from the gateway to when the full response has been received from the backend.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            An entire client HTTP transaction with a gateway, covered by the Request timeout,\n                            may result in more than one call from the gateway to the destination backend,\n                            for example, if automatic retries are supported.\n\n                            The value of BackendRequest must be a Gateway API Duration string as defined by\n                            GEP-2257.  When this field is unspecified, its behavior is implementation-specific;\n                            when specified, the value of BackendRequest must be no more than the value of the\n                            Request timeout (since the Request timeout encompasses the BackendRequest timeout).\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                        request:\n                          description: |-\n                            Request specifies the maximum duration for a gateway to respond to an HTTP request.\n                            If the gateway has not been able to respond before this deadline is met, the gateway\n                            MUST return a timeout error.\n\n                            For example, setting the `rules.timeouts.request` field to the value `10s` in an\n                            `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds\n                            to complete.\n\n                            Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\n                            completely. Implementations that cannot completely disable the timeout MUST\n                            instead interpret the zero duration as the longest possible value to which\n                            the timeout can be set.\n\n                            This timeout is intended to cover as close to the whole request-response transaction\n                            as possible although an implementation MAY choose to start the timeout after the entire\n                            request stream has been received instead of immediately after the transaction is\n                            initiated by the client.\n\n                            The value of Request is a Gateway API Duration string as defined by GEP-2257. When this\n                            field is unspecified, request timeout behavior is implementation-specific.\n\n                            Support: Extended\n                          pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$\n                          type: string\n                      type: object\n                      x-kubernetes-validations:\n                      - message: backendRequest timeout cannot be longer than request\n                          timeout\n                        rule: '!(has(self.request) && has(self.backendRequest) &&\n                          duration(self.request) != duration(''0s'') && duration(self.backendRequest)\n                          > duration(self.request))'\n                  type: object\n                  x-kubernetes-validations:\n                  - message: RequestRedirect filter must not be used together with\n                      backendRefs\n                    rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ?\n                      (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))):\n                      true'\n                  - message: When using RequestRedirect filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      ? ((size(self.matches) != 1 || !has(self.matches[0].path) ||\n                      self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: When using URLRewrite filter with path.replacePrefixMatch,\n                      exactly one PathPrefix match must be specified\n                    rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                  - message: Within backendRefs, when using RequestRedirect filter\n                      with path.replacePrefixMatch, exactly one PathPrefix match must\n                      be specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect)\n                      && has(f.requestRedirect.path) && f.requestRedirect.path.type\n                      == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch)))\n                      )) ? ((size(self.matches) != 1 || !has(self.matches[0].path)\n                      || self.matches[0].path.type != ''PathPrefix'') ? false : true)\n                      : true'\n                  - message: Within backendRefs, When using URLRewrite filter with\n                      path.replacePrefixMatch, exactly one PathPrefix match must be\n                      specified\n                    rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b,\n                      (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite)\n                      && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch''\n                      && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches)\n                      != 1 || !has(self.matches[0].path) || self.matches[0].path.type\n                      != ''PathPrefix'') ? false : true) : true'\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: While 16 rules and 64 matches per rule are allowed, the\n                    total number of matches across all rules in a route must be less\n                    than 128\n                  rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size()\n                    > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size()\n                    : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size()\n                    > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size()\n                    : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size()\n                    > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size()\n                    : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size()\n                    > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size()\n                    : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size()\n                    > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size()\n                    : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128'\n            type: object\n          status:\n            description: Status defines the current state of HTTPRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_listenersets.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: listenersets.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: ListenerSet\n    listKind: ListenerSetList\n    plural: listenersets\n    shortNames:\n    - lset\n    singular: listenerset\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .status.conditions[?(@.type==\"Accepted\")].status\n      name: Accepted\n      type: string\n    - jsonPath: .status.conditions[?(@.type==\"Programmed\")].status\n      name: Programmed\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ListenerSet defines a set of additional listeners to attach to an existing Gateway.\n          This resource provides a mechanism to merge multiple listeners into a single Gateway.\n\n          The parent Gateway must explicitly allow ListenerSet attachment through its\n          AllowedListeners configuration. By default, Gateways do not allow ListenerSet\n          attachment.\n\n          Routes can attach to a ListenerSet by specifying it as a parentRef, and can\n          optionally target specific listeners using the sectionName field.\n\n          Policy Attachment:\n          - Policies that attach to a ListenerSet apply to all listeners defined in that resource\n          - Policies do not impact listeners in the parent Gateway\n          - Different ListenerSets attached to the same Gateway can have different policies\n          - If an implementation cannot apply a policy to specific listeners, it should reject the policy\n\n          ReferenceGrant Semantics:\n          - ReferenceGrants applied to a Gateway are not inherited by child ListenerSets\n          - ReferenceGrants applied to a ListenerSet do not grant permission to the parent Gateway's listeners\n          - A ListenerSet can reference secrets/backends in its own namespace without a ReferenceGrant\n\n          Gateway Integration:\n            - The parent Gateway's status will include \"AttachedListenerSets\"\n              which is the count of ListenerSets that have successfully attached to a Gateway\n              A ListenerSet is successfully attached to a Gateway when all the following conditions are met:\n            - The ListenerSet is selected by the Gateway's AllowedListeners field\n            - The ListenerSet has a valid ParentRef selecting the Gateway\n            - The ListenerSet's status has the condition \"Accepted: true\"\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ListenerSet.\n            properties:\n              listeners:\n                description: |-\n                  Listeners associated with this ListenerSet. Listeners define\n                  logical endpoints that are bound on this referenced parent Gateway's addresses.\n\n                  Listeners in a `Gateway` and their attached `ListenerSets` are concatenated\n                  as a list when programming the underlying infrastructure. Each listener\n                  name does not need to be unique across the Gateway and ListenerSets.\n                  See ListenerEntry.Name for more details.\n\n                  Implementations MUST treat the parent Gateway as having the merged\n                  list of all listeners from itself and attached ListenerSets using\n                  the following precedence:\n\n                  1. \"parent\" Gateway\n                  2. ListenerSet ordered by creation time (oldest first)\n                  3. ListenerSet ordered alphabetically by \"{namespace}/{name}\".\n\n                  An implementation MAY reject listeners by setting the ListenerEntryStatus\n                  `Accepted` condition to False with the Reason `TooManyListeners`\n\n                  If a listener has a conflict, this will be reported in the\n                  Status.ListenerEntryStatus setting the `Conflicted` condition to True.\n\n                  Implementations SHOULD be cautious about what information from the\n                  parent or siblings are reported to avoid accidentally leaking\n                  sensitive information that the child would not otherwise have access\n                  to. This can include contents of secrets etc.\n                items:\n                  properties:\n                    allowedRoutes:\n                      default:\n                        namespaces:\n                          from: Same\n                      description: |-\n                        AllowedRoutes defines the types of routes that MAY be attached to a\n                        Listener and the trusted namespaces where those Route resources MAY be\n                        present.\n\n                        Although a client request may match multiple route rules, only one rule\n                        may ultimately receive the request. Matching precedence MUST be\n                        determined in order of the following criteria:\n\n                        * The most specific match as defined by the Route type.\n                        * The oldest Route based on creation timestamp. For example, a Route with\n                          a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over\n                          a Route with a creation timestamp of \"2020-09-08 01:02:04\".\n                        * If everything else is equivalent, the Route appearing first in\n                          alphabetical order (namespace/name) should be given precedence. For\n                          example, foo/bar is given precedence over foo/baz.\n\n                        All valid rules within a Route attached to this Listener should be\n                        implemented. Invalid Route rules can be ignored (sometimes that will mean\n                        the full Route). If a Route rule transitions from valid to invalid,\n                        support for that Route rule should be dropped to ensure consistency. For\n                        example, even if a filter specified by a Route rule is invalid, the rest\n                        of the rules within that Route should still be supported.\n                      properties:\n                        kinds:\n                          description: |-\n                            Kinds specifies the groups and kinds of Routes that are allowed to bind\n                            to this Gateway Listener. When unspecified or empty, the kinds of Routes\n                            selected are determined using the Listener protocol.\n\n                            A RouteGroupKind MUST correspond to kinds of Routes that are compatible\n                            with the application protocol specified in the Listener's Protocol field.\n                            If an implementation does not support or recognize this resource type, it\n                            MUST set the \"ResolvedRefs\" condition to False for this Listener with the\n                            \"InvalidRouteKinds\" reason.\n\n                            Support: Core\n                          items:\n                            description: RouteGroupKind indicates the group and kind\n                              of a Route resource.\n                            properties:\n                              group:\n                                default: gateway.networking.k8s.io\n                                description: Group is the group of the Route.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                description: Kind is the kind of the Route.\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                            required:\n                            - kind\n                            type: object\n                          maxItems: 8\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        namespaces:\n                          default:\n                            from: Same\n                          description: |-\n                            Namespaces indicates namespaces from which Routes may be attached to this\n                            Listener. This is restricted to the namespace of this Gateway by default.\n\n                            Support: Core\n                          properties:\n                            from:\n                              default: Same\n                              description: |-\n                                From indicates where Routes will be selected for this Gateway. Possible\n                                values are:\n\n                                * All: Routes in all namespaces may be used by this Gateway.\n                                * Selector: Routes in namespaces selected by the selector may be used by\n                                  this Gateway.\n                                * Same: Only Routes in the same namespace may be used by this Gateway.\n\n                                Support: Core\n                              enum:\n                              - All\n                              - Selector\n                              - Same\n                              type: string\n                            selector:\n                              description: |-\n                                Selector must be specified when From is set to \"Selector\". In that case,\n                                only Routes in Namespaces matching this Selector will be selected by this\n                                Gateway. This field is ignored for other values of \"From\".\n\n                                Support: Core\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label\n                                    selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the\n                                          selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                      type: object\n                    hostname:\n                      description: |-\n                        Hostname specifies the virtual hostname to match for protocol types that\n                        define this concept. When unspecified, all hostnames are matched. This\n                        field is ignored for protocols that don't require hostname based\n                        matching.\n\n                        Implementations MUST apply Hostname matching appropriately for each of\n                        the following protocols:\n\n                        * TLS: The Listener Hostname MUST match the SNI.\n                        * HTTP: The Listener Hostname MUST match the Host header of the request.\n                        * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP\n                          protocol layers as described above. If an implementation does not\n                          ensure that both the SNI and Host header match the Listener hostname,\n                          it MUST clearly document that.\n\n                        For HTTPRoute and TLSRoute resources, there is an interaction with the\n                        `spec.hostnames` array. When both listener and route specify hostnames,\n                        there MUST be an intersection between the values for a Route to be\n                        accepted. For more information, refer to the Route specific Hostnames\n                        documentation.\n\n                        Hostnames that are prefixed with a wildcard label (`*.`) are interpreted\n                        as a suffix match. That means that a match for `*.example.com` would match\n                        both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the Listener. This name MUST be unique within a\n                        ListenerSet.\n\n                        Name is not required to be unique across a Gateway and ListenerSets.\n                        Routes can attach to a Listener by having a ListenerSet as a parentRef\n                        and setting the SectionName\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port. Multiple listeners may use the\n                        same port, subject to the Listener compatibility rules.\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    protocol:\n                      description: Protocol specifies the network protocol this listener\n                        expects to receive.\n                      maxLength: 255\n                      minLength: 1\n                      pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$\n                      type: string\n                    tls:\n                      description: |-\n                        TLS is the TLS configuration for the Listener. This field is required if\n                        the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field\n                        if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\n                        The association of SNIs to Certificate defined in ListenerTLSConfig is\n                        defined based on the Hostname field for this listener.\n\n                        The GatewayClass MUST use the longest matching SNI out of all\n                        available certificates for any TLS handshake.\n                      properties:\n                        certificateRefs:\n                          description: |-\n                            CertificateRefs contains a series of references to Kubernetes objects that\n                            contains TLS certificates and private keys. These certificates are used to\n                            establish a TLS handshake for requests that match the hostname of the\n                            associated listener.\n\n                            A single CertificateRef to a Kubernetes Secret has \"Core\" support.\n                            Implementations MAY choose to support attaching multiple certificates to\n                            a Listener, but this behavior is implementation-specific.\n\n                            References to a resource in different namespace are invalid UNLESS there\n                            is a ReferenceGrant in the target namespace that allows the certificate\n                            to be attached. If a ReferenceGrant does not allow this reference, the\n                            \"ResolvedRefs\" condition MUST be set to False for this listener with the\n                            \"RefNotPermitted\" reason.\n\n                            This field is required to have at least one element when the mode is set\n                            to \"Terminate\" (default) and is optional otherwise.\n\n                            CertificateRefs can reference to standard Kubernetes resources, i.e.\n                            Secret, or implementation-specific custom resources.\n\n                            Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\n                            Support: Implementation-specific (More than one reference or other resource types)\n                          items:\n                            description: |-\n                              SecretObjectReference identifies an API object including its namespace,\n                              defaulting to Secret.\n\n                              The API object must be valid in the cluster; the Group and Kind must\n                              be registered in the cluster for this reference to be valid.\n\n                              References to objects with invalid Group and Kind are not valid, and must\n                              be rejected by the implementation, with appropriate Conditions set\n                              on the containing object.\n                            properties:\n                              group:\n                                default: \"\"\n                                description: |-\n                                  Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                                  When unspecified or empty string, core API group is inferred.\n                                maxLength: 253\n                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                                type: string\n                              kind:\n                                default: Secret\n                                description: Kind is kind of the referent. For example\n                                  \"Secret\".\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                                type: string\n                              name:\n                                description: Name is the name of the referent.\n                                maxLength: 253\n                                minLength: 1\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of the referenced object. When unspecified, the local\n                                  namespace is inferred.\n\n                                  Note that when a namespace different than the local namespace is specified,\n                                  a ReferenceGrant object is required in the referent namespace to allow that\n                                  namespace's owner to accept the reference. See the ReferenceGrant\n                                  documentation for details.\n\n                                  Support: Core\n                                maxLength: 63\n                                minLength: 1\n                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          maxItems: 64\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        mode:\n                          default: Terminate\n                          description: |-\n                            Mode defines the TLS behavior for the TLS session initiated by the client.\n                            There are two possible modes:\n\n                            - Terminate: The TLS session between the downstream client and the\n                              Gateway is terminated at the Gateway. This mode requires certificates\n                              to be specified in some way, such as populating the certificateRefs\n                              field.\n                            - Passthrough: The TLS session is NOT terminated by the Gateway. This\n                              implies that the Gateway can't decipher the TLS stream except for\n                              the ClientHello message of the TLS protocol. The certificateRefs field\n                              is ignored in this mode.\n\n                            Support: Core\n                          enum:\n                          - Terminate\n                          - Passthrough\n                          type: string\n                        options:\n                          additionalProperties:\n                            description: |-\n                              AnnotationValue is the value of an annotation in Gateway API. This is used\n                              for validation of maps such as TLS options. This roughly matches Kubernetes\n                              annotation validation, although the length validation in that case is based\n                              on the entire size of the annotations struct.\n                            maxLength: 4096\n                            minLength: 0\n                            type: string\n                          description: |-\n                            Options are a list of key/value pairs to enable extended TLS\n                            configuration for each implementation. For example, configuring the\n                            minimum TLS version or supported cipher suites.\n\n                            A set of common keys MAY be defined by the API in the future. To avoid\n                            any ambiguity, implementation-specific definitions MUST use\n                            domain-prefixed names, such as `example.com/my-custom-option`.\n                            Un-prefixed names are reserved for key names defined by Gateway API.\n\n                            Support: Implementation-specific\n                          maxProperties: 16\n                          type: object\n                      type: object\n                      x-kubernetes-validations:\n                      - message: certificateRefs or options must be specified when\n                          mode is Terminate\n                        rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs)\n                          > 0 || size(self.options) > 0 : true'\n                  required:\n                  - name\n                  - port\n                  - protocol\n                  type: object\n                maxItems: 64\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n                x-kubernetes-validations:\n                - message: tls must not be specified for protocols ['HTTP', 'TCP',\n                    'UDP']\n                  rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ?\n                    !has(l.tls) : true)'\n                - message: tls mode must be Terminate for protocol HTTPS\n                  rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode\n                    == '''' || l.tls.mode == ''Terminate'') : true)'\n                - message: tls mode must be set for protocol TLS\n                  rule: 'self.all(l, (l.protocol == ''TLS'' ? has(l.tls) && has(l.tls.mode)\n                    && l.tls.mode != '''' : true))'\n                - message: hostname must not be specified for protocols ['TCP', 'UDP']\n                  rule: 'self.all(l, l.protocol in [''TCP'', ''UDP'']  ? (!has(l.hostname)\n                    || l.hostname == '''') : true)'\n                - message: Listener name must be unique within the Gateway\n                  rule: self.all(l1, self.exists_one(l2, l1.name == l2.name))\n                - message: Combination of port, protocol and hostname must be unique\n                    for each listener\n                  rule: 'self.all(l1, !has(l1.port) || self.exists_one(l2, has(l2.port)\n                    && l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname)\n                    && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname)\n                    && !has(l2.hostname))))'\n              parentRef:\n                description: ParentRef references the Gateway that the listeners are\n                  attached to.\n                properties:\n                  group:\n                    default: gateway.networking.k8s.io\n                    description: Group is the group of the referent.\n                    maxLength: 253\n                    pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                    type: string\n                  kind:\n                    default: Gateway\n                    description: Kind is kind of the referent. For example \"Gateway\".\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                    type: string\n                  name:\n                    description: Name is the name of the referent.\n                    maxLength: 253\n                    minLength: 1\n                    type: string\n                  namespace:\n                    description: |-\n                      Namespace is the namespace of the referent.  If not present,\n                      the namespace of the referent is assumed to be the same as\n                      the namespace of the referring object.\n                    maxLength: 63\n                    minLength: 1\n                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                    type: string\n                required:\n                - name\n                type: object\n            required:\n            - listeners\n            - parentRef\n            type: object\n          status:\n            default:\n              conditions:\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Accepted\n              - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                message: Waiting for controller\n                reason: Pending\n                status: Unknown\n                type: Programmed\n            description: Status defines the current state of ListenerSet.\n            properties:\n              conditions:\n                default:\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Accepted\n                - lastTransitionTime: \"1970-01-01T00:00:00Z\"\n                  message: Waiting for controller\n                  reason: Pending\n                  status: Unknown\n                  type: Programmed\n                description: |-\n                  Conditions describe the current conditions of the ListenerSet.\n\n                  Implementations MUST express ListenerSet conditions using the\n                  `ListenerSetConditionType` and `ListenerSetConditionReason`\n                  constants so that operators and tools can converge on a common\n                  vocabulary to describe ListenerSet state.\n\n                  Known condition types are:\n\n                  * \"Accepted\"\n                  * \"Programmed\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      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])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                maxItems: 8\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              listeners:\n                description: Listeners provide status for each unique listener port\n                  defined in the Spec.\n                items:\n                  description: ListenerStatus is the status associated with a Listener.\n                  properties:\n                    attachedRoutes:\n                      description: |-\n                        AttachedRoutes represents the total number of Routes that have been\n                        successfully attached to this Listener.\n\n                        Successful attachment of a Route to a Listener is based solely on the\n                        combination of the AllowedRoutes field on the corresponding Listener\n                        and the Route's ParentRefs field. A Route is successfully attached to\n                        a Listener when it is selected by the Listener's AllowedRoutes field\n                        AND the Route has a valid ParentRef selecting the whole Gateway\n                        resource or a specific Listener as a parent resource (more detail on\n                        attachment semantics can be found in the documentation on the various\n                        Route kinds ParentRefs fields). Listener status does not impact\n                        successful attachment, i.e. the AttachedRoutes field count MUST be set\n                        for Listeners, even if the Accepted condition of an individual Listener is set\n                        to \"False\". The AttachedRoutes number represents the number of Routes with\n                        the Accepted condition set to \"True\" that have been attached to this Listener.\n                        Routes with any other value for the Accepted condition MUST NOT be included\n                        in this count.\n\n                        Uses for this field include troubleshooting Route attachment and\n                        measuring blast radius/impact of changes to a Listener.\n                      format: int32\n                      type: integer\n                    conditions:\n                      description: Conditions describe the current condition of this\n                        listener.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    name:\n                      description: Name is the name of the Listener that this status\n                        corresponds to.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    supportedKinds:\n                      description: |-\n                        SupportedKinds is the list indicating the Kinds supported by this\n                        listener. This MUST represent the kinds supported by an implementation for\n                        that Listener configuration.\n\n                        If kinds are specified in Spec that are not supported, they MUST NOT\n                        appear in this list and an implementation MUST set the \"ResolvedRefs\"\n                        condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid\n                        and invalid Route kinds are specified, the implementation MUST\n                        reference the valid Route kinds that have been specified.\n                      items:\n                        description: RouteGroupKind indicates the group and kind of\n                          a Route resource.\n                        properties:\n                          group:\n                            default: gateway.networking.k8s.io\n                            description: Group is the group of the Route.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            description: Kind is the kind of the Route.\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                        required:\n                        - kind\n                        type: object\n                      maxItems: 8\n                      type: array\n                      x-kubernetes-list-type: atomic\n                  required:\n                  - attachedRoutes\n                  - conditions\n                  - name\n                  type: object\n                maxItems: 64\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_referencegrants.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: referencegrants.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: ReferenceGrant\n    listKind: ReferenceGrantList\n    plural: referencegrants\n    shortNames:\n    - refgrant\n    singular: referencegrant\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ReferenceGrant identifies kinds of resources in other namespaces that are\n          trusted to reference the specified kinds of resources in the same namespace\n          as the policy.\n\n          Each ReferenceGrant can be used to represent a unique trust relationship.\n          Additional Reference Grants can be used to add to the set of trusted\n          sources of inbound references for the namespace they are defined within.\n\n          All cross-namespace references in Gateway API (with the exception of cross-namespace\n          Gateway-route attachment) require a ReferenceGrant.\n\n          ReferenceGrant is a form of runtime verification allowing users to assert\n          which cross-namespace object references are permitted. Implementations that\n          support ReferenceGrant MUST NOT permit cross-namespace references which have\n          no grant, and MUST respond to the removal of a grant by revoking the access\n          that the grant allowed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ReferenceGrant.\n            properties:\n              from:\n                description: |-\n                  From describes the trusted namespaces and kinds that can reference the\n                  resources described in \"To\". Each entry in this list MUST be considered\n                  to be an additional place that references can be valid from, or to put\n                  this another way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: ReferenceGrantFrom describes trusted namespaces and\n                    kinds.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field.\n\n                        When used to permit a SecretObjectReference:\n\n                        * Gateway\n\n                        When used to permit a BackendObjectReference:\n\n                        * GRPCRoute\n                        * HTTPRoute\n                        * TCPRoute\n                        * TLSRoute\n                        * UDPRoute\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - namespace\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n              to:\n                description: |-\n                  To describes the resources that may be referenced by the resources\n                  described in \"From\". Each entry in this list MUST be considered to be an\n                  additional place that references can be valid to, or to put this another\n                  way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: |-\n                    ReferenceGrantTo describes what Kinds are allowed as targets of the\n                    references.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field:\n\n                        * Secret when used to permit a SecretObjectReference\n                        * Service when used to permit a BackendObjectReference\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent. When unspecified, this policy\n                        refers to all resources of the specified Group and Kind in the local\n                        namespace.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - from\n            - to\n            type: object\n        type: object\n    served: true\n    storage: false\n    subresources: {}\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1beta1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ReferenceGrant identifies kinds of resources in other namespaces that are\n          trusted to reference the specified kinds of resources in the same namespace\n          as the policy.\n\n          Each ReferenceGrant can be used to represent a unique trust relationship.\n          Additional Reference Grants can be used to add to the set of trusted\n          sources of inbound references for the namespace they are defined within.\n\n          All cross-namespace references in Gateway API (with the exception of cross-namespace\n          Gateway-route attachment) require a ReferenceGrant.\n\n          ReferenceGrant is a form of runtime verification allowing users to assert\n          which cross-namespace object references are permitted. Implementations that\n          support ReferenceGrant MUST NOT permit cross-namespace references which have\n          no grant, and MUST respond to the removal of a grant by revoking the access\n          that the grant allowed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of ReferenceGrant.\n            properties:\n              from:\n                description: |-\n                  From describes the trusted namespaces and kinds that can reference the\n                  resources described in \"To\". Each entry in this list MUST be considered\n                  to be an additional place that references can be valid from, or to put\n                  this another way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: ReferenceGrantFrom describes trusted namespaces and\n                    kinds.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field.\n\n                        When used to permit a SecretObjectReference:\n\n                        * Gateway\n\n                        When used to permit a BackendObjectReference:\n\n                        * GRPCRoute\n                        * HTTPRoute\n                        * TCPRoute\n                        * TLSRoute\n                        * UDPRoute\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  - namespace\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n              to:\n                description: |-\n                  To describes the resources that may be referenced by the resources\n                  described in \"From\". Each entry in this list MUST be considered to be an\n                  additional place that references can be valid to, or to put this another\n                  way, entries MUST be combined using OR.\n\n                  Support: Core\n                items:\n                  description: |-\n                    ReferenceGrantTo describes what Kinds are allowed as targets of the\n                    references.\n                  properties:\n                    group:\n                      description: |-\n                        Group is the group of the referent.\n                        When empty, the Kubernetes core API group is inferred.\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      description: |-\n                        Kind is the kind of the referent. Although implementations may support\n                        additional resources, the following types are part of the \"Core\"\n                        support level for this field:\n\n                        * Secret when used to permit a SecretObjectReference\n                        * Service when used to permit a BackendObjectReference\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent. When unspecified, this policy\n                        refers to all resources of the specified Group and Kind in the local\n                        namespace.\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                  required:\n                  - group\n                  - kind\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - from\n            - to\n            type: object\n        type: object\n    served: true\n    storage: true\n    subresources: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_tlsroutes.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328\n    gateway.networking.k8s.io/bundle-version: v1.4.1\n    gateway.networking.k8s.io/channel: standard\n  name: tlsroutes.gateway.networking.k8s.io\nspec:\n  group: gateway.networking.k8s.io\n  names:\n    categories:\n    - gateway-api\n    kind: TLSRoute\n    listKind: TLSRouteList\n    plural: tlsroutes\n    singular: tlsroute\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The TLSRoute resource is similar to TCPRoute, but can be configured\n          to match against TLS-specific metadata. This allows more flexibility\n          in matching streams for a given TLS listener.\n\n          If you need to forward traffic to a single target for a TLS listener, you\n          could choose to use a TCPRoute with a TLS listener.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TLSRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of SNI hostnames that should match against the\n                  SNI attribute of TLS ClientHello message in TLS handshake. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed in SNI hostnames per RFC 6066.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Hostnames cannot contain an IP\n                  rule: self.all(h, !isIP(h))\n                - message: Hostnames must be valid based on RFC-1123\n                  rule: 'self.all(h, !h.contains(''*'') ? h.matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$'')\n                    : true)'\n                - message: Wildcards on hostnames must be the first label, and the\n                    rest of hostname must be valid based on RFC-1123\n                  rule: 'self.all(h, h.contains(''*'') ? (h.startsWith(''*.'') &&\n                    h.substring(2).matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$''))\n                    : true)'\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''')) : true))'\n                - message: sectionName must be unique when parentRefs includes 2 or\n                    more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              rules:\n                description: Rules are a list of actions.\n                items:\n                  description: TLSRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or\n                        a Service with no endpoints), the rule performs no forwarding; if no\n                        filters are specified that would result in a response being sent, the\n                        underlying implementation must actively reject request attempts to this\n                        backend, by rejecting the connection or returning a 500 status code.\n                        Request rejections must respect weight; if an invalid backend is\n                        requested to have 80% of requests, then 80% of requests must be rejected\n                        instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: Name is the name of the route rule. This name MUST\n                        be unique within a Route if it is set.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 1\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - hostnames\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TLSRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    deprecated: true\n    deprecationWarning: The v1alpha2 version of TLSRoute has been deprecated and will\n      be removed in a future release of the API. Please upgrade to v1.\n    name: v1alpha2\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The TLSRoute resource is similar to TCPRoute, but can be configured\n          to match against TLS-specific metadata. This allows more flexibility\n          in matching streams for a given TLS listener.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TLSRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of SNI names that should match against the\n                  SNI attribute of TLS ClientHello message in TLS handshake. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed in SNI names per RFC 6066.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n\n                  If a hostname is specified by both the Listener and TLSRoute, there\n                  must be at least one intersecting hostname for the TLSRoute to be\n                  attached to the Listener. For example:\n\n                  * A Listener with `test.example.com` as the hostname matches TLSRoutes\n                    that have either not specified any hostnames, or have specified at\n                    least one of `test.example.com` or `*.example.com`.\n                  * A Listener with `*.example.com` as the hostname matches TLSRoutes\n                    that have either not specified any hostnames or have specified at least\n                    one hostname that matches the Listener hostname. For example,\n                    `test.example.com` and `*.example.com` would both match. On the other\n                    hand, `example.com` and `test.example.net` would not match.\n\n                  If both the Listener and TLSRoute have specified hostnames, any\n                  TLSRoute hostnames that do not match the Listener hostname MUST be\n                  ignored. For example, if a Listener specified `*.example.com`, and the\n                  TLSRoute specified `test.example.com` and `test.example.net`,\n                  `test.example.net` must not be considered for a match.\n\n                  If both the Listener and TLSRoute have specified hostnames, and none\n                  match with the criteria above, then the TLSRoute is not accepted. The\n                  implementation must raise an 'Accepted' Condition with a status of\n                  `False` in the corresponding RouteParentStatus.\n\n                  Support: Core\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                type: array\n                x-kubernetes-list-type: atomic\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''')) : true))'\n                - message: sectionName must be unique when parentRefs includes 2 or\n                    more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              rules:\n                description: Rules are a list of TLS matchers and actions.\n                items:\n                  description: TLSRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or\n                        a Service with no endpoints), the rule performs no forwarding; if no\n                        filters are specified that would result in a response being sent, the\n                        underlying implementation must actively reject request attempts to this\n                        backend, by rejecting the connection or returning a 500 status code.\n                        Request rejections must respect weight; if an invalid backend is\n                        requested to have 80% of requests, then 80% of requests must be rejected\n                        instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: Name is the name of the route rule. This name MUST\n                        be unique within a Route if it is set.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TLSRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: false\n    storage: false\n    subresources:\n      status: {}\n  - additionalPrinterColumns:\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    deprecated: true\n    deprecationWarning: The v1alpha3 version of TLSRoute has been deprecated and will\n      be removed in a future release of the API. Please upgrade to v1.\n    name: v1alpha3\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The TLSRoute resource is similar to TCPRoute, but can be configured\n          to match against TLS-specific metadata. This allows more flexibility\n          in matching streams for a given TLS listener.\n\n          If you need to forward traffic to a single target for a TLS listener, you\n          could choose to use a TCPRoute with a TLS listener.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec defines the desired state of TLSRoute.\n            properties:\n              hostnames:\n                description: |-\n                  Hostnames defines a set of SNI hostnames that should match against the\n                  SNI attribute of TLS ClientHello message in TLS handshake. This matches\n                  the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                  1. IPs are not allowed in SNI hostnames per RFC 6066.\n                  2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                     label must appear by itself as the first label.\n                items:\n                  description: |-\n                    Hostname is the fully qualified domain name of a network host. This matches\n                    the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n                     1. IPs are not allowed.\n                     2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n                        label must appear by itself as the first label.\n\n                    Hostname can be \"precise\" which is a domain name without the terminating\n                    dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a\n                    domain name prefixed with a single wildcard label (e.g. `*.example.com`).\n\n                    Note that as per RFC1035 and RFC1123, a *label* must consist of lower case\n                    alphanumeric characters or '-', and must start and end with an alphanumeric\n                    character. No other punctuation is allowed.\n                  maxLength: 253\n                  minLength: 1\n                  pattern: ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                  type: string\n                maxItems: 16\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: Hostnames cannot contain an IP\n                  rule: self.all(h, !isIP(h))\n                - message: Hostnames must be valid based on RFC-1123\n                  rule: 'self.all(h, !h.contains(''*'') ? h.matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$'')\n                    : true)'\n                - message: Wildcards on hostnames must be the first label, and the\n                    rest of hostname must be valid based on RFC-1123\n                  rule: 'self.all(h, h.contains(''*'') ? (h.startsWith(''*.'') &&\n                    h.substring(2).matches(''^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$''))\n                    : true)'\n              parentRefs:\n                description: |-\n                  ParentRefs references the resources (usually Gateways) that a Route wants\n                  to be attached to. Note that the referenced parent resource needs to\n                  allow this for the attachment to be complete. For Gateways, that means\n                  the Gateway needs to allow attachment from Routes of this kind and\n                  namespace. For Services, that means the Service must either be in the same\n                  namespace for a \"producer\" route, or the mesh implementation must support\n                  and allow \"consumer\" routes for the referenced Service. ReferenceGrant is\n                  not applicable for governing ParentRefs to Services - it is not possible to\n                  create a \"producer\" route for a Service in a different namespace from the\n                  Route.\n\n                  There are two kinds of parent resources with \"Core\" support:\n\n                  * Gateway (Gateway conformance profile)\n                  * Service (Mesh conformance profile, ClusterIP Services only)\n\n                  This API may be extended in the future to support additional kinds of parent\n                  resources.\n\n                  ParentRefs must be _distinct_. This means either that:\n\n                  * They select different objects.  If this is the case, then parentRef\n                    entries are distinct. In terms of fields, this means that the\n                    multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n                    be unique across all parentRef entries in the Route.\n                  * They do not select different objects, but for each optional field used,\n                    each ParentRef that selects the same object must set the same set of\n                    optional fields to different values. If one ParentRef sets a\n                    combination of optional fields, all must set the same combination.\n\n                  Some examples:\n\n                  * If one ParentRef sets `sectionName`, all ParentRefs referencing the\n                    same object must also set `sectionName`.\n                  * If one ParentRef sets `port`, all ParentRefs referencing the same\n                    object must also set `port`.\n                  * If one ParentRef sets `sectionName` and `port`, all ParentRefs\n                    referencing the same object must also set `sectionName` and `port`.\n\n                  It is possible to separately reference multiple distinct objects that may\n                  be collapsed by an implementation. For example, some implementations may\n                  choose to merge compatible Gateway Listeners together. If that is the\n                  case, the list of routes attached to those resources should also be\n                  merged.\n\n                  Note that for ParentRefs that cross namespace boundaries, there are specific\n                  rules. Cross-namespace references are only valid if they are explicitly\n                  allowed by something in the namespace they are referring to. For example,\n                  Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                  generic way to enable other kinds of cross-namespace reference.\n                items:\n                  description: |-\n                    ParentReference identifies an API object (usually a Gateway) that can be considered\n                    a parent of this resource (usually a route). There are two kinds of parent resources\n                    with \"Core\" support:\n\n                    * Gateway (Gateway conformance profile)\n                    * Service (Mesh conformance profile, ClusterIP Services only)\n\n                    This API may be extended in the future to support additional kinds of parent\n                    resources.\n\n                    The API object must be valid in the cluster; the Group and Kind must\n                    be registered in the cluster for this reference to be valid.\n                  properties:\n                    group:\n                      default: gateway.networking.k8s.io\n                      description: |-\n                        Group is the group of the referent.\n                        When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                        To set the core API group (such as for a \"Service\" kind referent),\n                        Group must be explicitly set to \"\" (empty string).\n\n                        Support: Core\n                      maxLength: 253\n                      pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                    kind:\n                      default: Gateway\n                      description: |-\n                        Kind is kind of the referent.\n\n                        There are two kinds of parent resources with \"Core\" support:\n\n                        * Gateway (Gateway conformance profile)\n                        * Service (Mesh conformance profile, ClusterIP Services only)\n\n                        Support for other resources is Implementation-Specific.\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                      type: string\n                    name:\n                      description: |-\n                        Name is the name of the referent.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace is the namespace of the referent. When unspecified, this refers\n                        to the local namespace of the Route.\n\n                        Note that there are specific rules for ParentRefs which cross namespace\n                        boundaries. Cross-namespace references are only valid if they are explicitly\n                        allowed by something in the namespace they are referring to. For example:\n                        Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                        generic way to enable any other kind of cross-namespace reference.\n\n                        Support: Core\n                      maxLength: 63\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                      type: string\n                    port:\n                      description: |-\n                        Port is the network port this Route targets. It can be interpreted\n                        differently based on the type of parent resource.\n\n                        When the parent resource is a Gateway, this targets all listeners\n                        listening on the specified port that also support this kind of Route(and\n                        select this Route). It's not recommended to set `Port` unless the\n                        networking behaviors specified in a Route must apply to a specific port\n                        as opposed to a listener(s) whose port(s) may be changed. When both Port\n                        and SectionName are specified, the name and port of the selected listener\n                        must match both specified values.\n\n                        Implementations MAY choose to support other parent resources.\n                        Implementations supporting other types of parent resources MUST clearly\n                        document how/if Port is interpreted.\n\n                        For the purpose of status, an attachment is considered successful as\n                        long as the parent resource accepts it partially. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                        from the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route,\n                        the Route MUST be considered detached from the Gateway.\n\n                        Support: Extended\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    sectionName:\n                      description: |-\n                        SectionName is the name of a section within the target resource. In the\n                        following resources, SectionName is interpreted as the following:\n\n                        * Gateway: Listener name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n                        * Service: Port name. When both Port (experimental) and SectionName\n                        are specified, the name and port of the selected listener must match\n                        both specified values.\n\n                        Implementations MAY choose to support attaching Routes to other resources.\n                        If that is the case, they MUST clearly document how SectionName is\n                        interpreted.\n\n                        When unspecified (empty string), this will reference the entire resource.\n                        For the purpose of status, an attachment is considered successful if at\n                        least one section in the parent resource accepts it. For example, Gateway\n                        listeners can restrict which Routes can attach to them by Route kind,\n                        namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                        the referencing Route, the Route MUST be considered successfully\n                        attached. If no Gateway listeners accept attachment from this Route, the\n                        Route MUST be considered detached from the Gateway.\n\n                        Support: Core\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - name\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n                x-kubernetes-validations:\n                - message: sectionName must be specified when parentRefs includes\n                    2 or more references to the same parent\n                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName)\n                    || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName\n                    == '''')) : true))'\n                - message: sectionName must be unique when parentRefs includes 2 or\n                    more references to the same parent\n                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind\n                    == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__)\n                    || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__\n                    == '')) || (has(p1.__namespace__) && has(p2.__namespace__) &&\n                    p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName)\n                    || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName\n                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName\n                    == p2.sectionName))))\n              rules:\n                description: Rules are a list of actions.\n                items:\n                  description: TLSRouteRule is the configuration for a given rule.\n                  properties:\n                    backendRefs:\n                      description: |-\n                        BackendRefs defines the backend(s) where matching requests should be\n                        sent. If unspecified or invalid (refers to a nonexistent resource or\n                        a Service with no endpoints), the rule performs no forwarding; if no\n                        filters are specified that would result in a response being sent, the\n                        underlying implementation must actively reject request attempts to this\n                        backend, by rejecting the connection or returning a 500 status code.\n                        Request rejections must respect weight; if an invalid backend is\n                        requested to have 80% of requests, then 80% of requests must be rejected\n                        instead.\n\n                        Support: Core for Kubernetes Service\n\n                        Support: Extended for Kubernetes ServiceImport\n\n                        Support: Implementation-specific for any other resource\n\n                        Support for weight: Extended\n                      items:\n                        description: |-\n                          BackendRef defines how a Route should forward a request to a Kubernetes\n                          resource.\n\n                          Note that when a namespace different than the local namespace is specified, a\n                          ReferenceGrant object is required in the referent namespace to allow that\n                          namespace's owner to accept the reference. See the ReferenceGrant\n                          documentation for details.\n\n                          Note that when the BackendTLSPolicy object is enabled by the implementation,\n                          there are some extra rules about validity to consider here. See the fields\n                          where this struct is used for more information about the exact behavior.\n                        properties:\n                          group:\n                            default: \"\"\n                            description: |-\n                              Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\n                              When unspecified or empty string, core API group is inferred.\n                            maxLength: 253\n                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                            type: string\n                          kind:\n                            default: Service\n                            description: |-\n                              Kind is the Kubernetes resource kind of the referent. For example\n                              \"Service\".\n\n                              Defaults to \"Service\" when not specified.\n\n                              ExternalName services can refer to CNAME DNS records that may live\n                              outside of the cluster and as such are difficult to reason about in\n                              terms of conformance. They also may not be safe to forward to (see\n                              CVE-2021-25740 for more information). Implementations SHOULD NOT\n                              support ExternalName Services.\n\n                              Support: Core (Services with a type other than ExternalName)\n\n                              Support: Implementation-specific (Services with type ExternalName)\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                            type: string\n                          name:\n                            description: Name is the name of the referent.\n                            maxLength: 253\n                            minLength: 1\n                            type: string\n                          namespace:\n                            description: |-\n                              Namespace is the namespace of the backend. When unspecified, the local\n                              namespace is inferred.\n\n                              Note that when a namespace different than the local namespace is specified,\n                              a ReferenceGrant object is required in the referent namespace to allow that\n                              namespace's owner to accept the reference. See the ReferenceGrant\n                              documentation for details.\n\n                              Support: Core\n                            maxLength: 63\n                            minLength: 1\n                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                            type: string\n                          port:\n                            description: |-\n                              Port specifies the destination port number to use for this resource.\n                              Port is required when the referent is a Kubernetes Service. In this\n                              case, the port number is the service port number, not the target port.\n                              For other resources, destination port might be derived from the referent\n                              resource or this field.\n                            format: int32\n                            maximum: 65535\n                            minimum: 1\n                            type: integer\n                          weight:\n                            default: 1\n                            description: |-\n                              Weight specifies the proportion of requests forwarded to the referenced\n                              backend. This is computed as weight/(sum of all weights in this\n                              BackendRefs list). For non-zero values, there may be some epsilon from\n                              the exact proportion defined here depending on the precision an\n                              implementation supports. Weight is not a percentage and the sum of\n                              weights does not need to equal 100.\n\n                              If only one backend is specified and it has a weight greater than 0, 100%\n                              of the traffic is forwarded to that backend. If weight is set to 0, no\n                              traffic should be forwarded for this entry. If unspecified, weight\n                              defaults to 1.\n\n                              Support for this field varies based on the context where used.\n                            format: int32\n                            maximum: 1000000\n                            minimum: 0\n                            type: integer\n                        required:\n                        - name\n                        type: object\n                        x-kubernetes-validations:\n                        - message: Must have port for Service reference\n                          rule: '(size(self.group) == 0 && self.kind == ''Service'')\n                            ? has(self.port) : true'\n                      maxItems: 16\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    name:\n                      description: Name is the name of the route rule. This name MUST\n                        be unique within a Route if it is set.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                      type: string\n                  required:\n                  - backendRefs\n                  type: object\n                maxItems: 1\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - hostnames\n            - rules\n            type: object\n          status:\n            description: Status defines the current state of TLSRoute.\n            properties:\n              parents:\n                description: |-\n                  Parents is a list of parent resources (usually Gateways) that are\n                  associated with the route, and the status of the route with respect to\n                  each parent. When this route attaches to a parent, the controller that\n                  manages the parent must add an entry to this list when the controller\n                  first sees the route and should update the entry as appropriate when the\n                  route or gateway is modified.\n\n                  Note that parent references that cannot be resolved by an implementation\n                  of this API will not be added to this list. Implementations of this API\n                  can only populate Route status for the Gateways/parent resources they are\n                  responsible for.\n\n                  A maximum of 32 Gateways will be represented in this list. An empty list\n                  means the route has not been attached to any Gateway.\n                items:\n                  description: |-\n                    RouteParentStatus describes the status of a route with respect to an\n                    associated Parent.\n                  properties:\n                    conditions:\n                      description: |-\n                        Conditions describes the status of the route with respect to the Gateway.\n                        Note that the route's availability is also subject to the Gateway's own\n                        status conditions and listener status.\n\n                        If the Route's ParentRef specifies an existing Gateway that supports\n                        Routes of this kind AND that Gateway's controller has sufficient access,\n                        then that Gateway's controller MUST set the \"Accepted\" condition on the\n                        Route, to indicate whether the route has been accepted or rejected by the\n                        Gateway, and why.\n\n                        A Route MUST be considered \"Accepted\" if at least one of the Route's\n                        rules is implemented by the Gateway.\n\n                        There are a number of cases where the \"Accepted\" condition may not be set\n                        due to lack of controller visibility, that includes when:\n\n                        * The Route refers to a nonexistent parent.\n                        * The Route is of a type that the controller does not support.\n                        * The Route is in a namespace to which the controller does not have access.\n                      items:\n                        description: Condition contains details for one aspect of\n                          the current state of this API Resource.\n                        properties:\n                          lastTransitionTime:\n                            description: |-\n                              lastTransitionTime is the last time the condition transitioned from one status to another.\n                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                            format: date-time\n                            type: string\n                          message:\n                            description: |-\n                              message is a human readable message indicating details about the transition.\n                              This may be an empty string.\n                            maxLength: 32768\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              observedGeneration represents the .metadata.generation that the condition was set based upon.\n                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                              with respect to the current state of the instance.\n                            format: int64\n                            minimum: 0\n                            type: integer\n                          reason:\n                            description: |-\n                              reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                              Producers of specific condition types may define expected values and meanings for this field,\n                              and whether the values are considered a guaranteed API.\n                              The value should be a CamelCase string.\n                              This field may not be empty.\n                            maxLength: 1024\n                            minLength: 1\n                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                            type: string\n                          status:\n                            description: status of the condition, one of True, False,\n                              Unknown.\n                            enum:\n                            - \"True\"\n                            - \"False\"\n                            - Unknown\n                            type: string\n                          type:\n                            description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                            maxLength: 316\n                            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])$\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - message\n                        - reason\n                        - status\n                        - type\n                        type: object\n                      maxItems: 8\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    controllerName:\n                      description: |-\n                        ControllerName is a domain/path string that indicates the name of the\n                        controller that wrote this status. This corresponds with the\n                        controllerName field on GatewayClass.\n\n                        Example: \"example.net/gateway-controller\".\n\n                        The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are\n                        valid Kubernetes names\n                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\n                        Controllers MUST populate this field when writing status. Controllers should ensure that\n                        entries to status populated with their ControllerName are cleaned up when they are no\n                        longer necessary.\n                      maxLength: 253\n                      minLength: 1\n                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$\n                      type: string\n                    parentRef:\n                      description: |-\n                        ParentRef corresponds with a ParentRef in the spec that this\n                        RouteParentStatus struct describes the status of.\n                      properties:\n                        group:\n                          default: gateway.networking.k8s.io\n                          description: |-\n                            Group is the group of the referent.\n                            When unspecified, \"gateway.networking.k8s.io\" is inferred.\n                            To set the core API group (such as for a \"Service\" kind referent),\n                            Group must be explicitly set to \"\" (empty string).\n\n                            Support: Core\n                          maxLength: 253\n                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                        kind:\n                          default: Gateway\n                          description: |-\n                            Kind is kind of the referent.\n\n                            There are two kinds of parent resources with \"Core\" support:\n\n                            * Gateway (Gateway conformance profile)\n                            * Service (Mesh conformance profile, ClusterIP Services only)\n\n                            Support for other resources is Implementation-Specific.\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$\n                          type: string\n                        name:\n                          description: |-\n                            Name is the name of the referent.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace is the namespace of the referent. When unspecified, this refers\n                            to the local namespace of the Route.\n\n                            Note that there are specific rules for ParentRefs which cross namespace\n                            boundaries. Cross-namespace references are only valid if they are explicitly\n                            allowed by something in the namespace they are referring to. For example:\n                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a\n                            generic way to enable any other kind of cross-namespace reference.\n\n                            Support: Core\n                          maxLength: 63\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\n                          type: string\n                        port:\n                          description: |-\n                            Port is the network port this Route targets. It can be interpreted\n                            differently based on the type of parent resource.\n\n                            When the parent resource is a Gateway, this targets all listeners\n                            listening on the specified port that also support this kind of Route(and\n                            select this Route). It's not recommended to set `Port` unless the\n                            networking behaviors specified in a Route must apply to a specific port\n                            as opposed to a listener(s) whose port(s) may be changed. When both Port\n                            and SectionName are specified, the name and port of the selected listener\n                            must match both specified values.\n\n                            Implementations MAY choose to support other parent resources.\n                            Implementations supporting other types of parent resources MUST clearly\n                            document how/if Port is interpreted.\n\n                            For the purpose of status, an attachment is considered successful as\n                            long as the parent resource accepts it partially. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment\n                            from the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route,\n                            the Route MUST be considered detached from the Gateway.\n\n                            Support: Extended\n                          format: int32\n                          maximum: 65535\n                          minimum: 1\n                          type: integer\n                        sectionName:\n                          description: |-\n                            SectionName is the name of a section within the target resource. In the\n                            following resources, SectionName is interpreted as the following:\n\n                            * Gateway: Listener name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n                            * Service: Port name. When both Port (experimental) and SectionName\n                            are specified, the name and port of the selected listener must match\n                            both specified values.\n\n                            Implementations MAY choose to support attaching Routes to other resources.\n                            If that is the case, they MUST clearly document how SectionName is\n                            interpreted.\n\n                            When unspecified (empty string), this will reference the entire resource.\n                            For the purpose of status, an attachment is considered successful if at\n                            least one section in the parent resource accepts it. For example, Gateway\n                            listeners can restrict which Routes can attach to them by Route kind,\n                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from\n                            the referencing Route, the Route MUST be considered successfully\n                            attached. If no Gateway listeners accept attachment from this Route, the\n                            Route MUST be considered detached from the Gateway.\n\n                            Support: Core\n                          maxLength: 253\n                          minLength: 1\n                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\n                          type: string\n                      required:\n                      - name\n                      type: object\n                  required:\n                  - conditions\n                  - controllerName\n                  - parentRef\n                  type: object\n                maxItems: 32\n                type: array\n                x-kubernetes-list-type: atomic\n            required:\n            - parents\n            type: object\n        required:\n        - spec\n        type: object\n    served: false\n    storage: false\n    subresources:\n      status: {}\nstatus:\n  acceptedNames:\n    kind: \"\"\n    plural: \"\"\n  conditions: null\n  storedVersions: null\n"
  },
  {
    "path": "pkg/gateway/crds/standard/gateway.networking.k8s.io_vap_safeupgrades.yaml",
    "content": "apiVersion: admissionregistration.k8s.io/v1\nkind: ValidatingAdmissionPolicy\nmetadata:\n  annotations:\n    gateway.networking.k8s.io/bundle-version: v1.5.0-dev\n    gateway.networking.k8s.io/channel: standard\n  name: \"safe-upgrades.gateway.networking.k8s.io\"\nspec:\n  failurePolicy: Fail\n  matchConstraints:\n    resourceRules:\n    - apiGroups:   [\"apiextensions.k8s.io\"]\n      apiVersions: [\"v1\"]\n      operations:  [\"CREATE\", \"UPDATE\"]\n      resources:   [\"*\"]\n  validations:\n    - expression: \"object.spec.group != 'gateway.networking.k8s.io' || (\n        has(object.metadata.annotations) && object.metadata.annotations.exists(k, k == 'gateway.networking.k8s.io/channel') && \n        object.metadata.annotations['gateway.networking.k8s.io/channel'] == 'standard' )\"\n      message: \"Installing experimental CRDs on top of standard channel CRDs is prohibited by default. Uninstall ValidatingAdmissionPolicy safe-upgrades.gateway.networking.k8s.io to install experimental CRDs on top of standard channel CRDs.\"\n      reason: Invalid\n    - expression: \"object.spec.group != 'gateway.networking.k8s.io' || \n        (has(object.metadata.annotations) && object.metadata.annotations.exists(k, k == 'gateway.networking.k8s.io/bundle-version') && \n        !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], 'v1.[0-3].\\\\\\\\d+') &&\n        !matches(object.metadata.annotations['gateway.networking.k8s.io/bundle-version'], 'v0'))\" #TODO Kubernetes 1.37: Migrate to kubernetes semver library\n      message: \"Installing CRDs with version before v1.5.0 is prohibited by default. Uninstall ValidatingAdmissionPolicy safe-upgrades.gateway.networking.k8s.io to install older versions.\"\n      reason: Invalid\n\n---\n\napiVersion: admissionregistration.k8s.io/v1\nkind: ValidatingAdmissionPolicyBinding\nmetadata:\n  annotations:\n    gateway.networking.k8s.io/bundle-version: v1.5.0-dev\n    gateway.networking.k8s.io/channel: standard\n  name: safe-upgrades.gateway.networking.k8s.io\nspec:\n  policyName: safe-upgrades.gateway.networking.k8s.io\n  validationActions: [Deny]\n  matchResources:\n    resourceRules:\n    - apiGroups:   [\"apiextensions.k8s.io\"]\n      apiVersions: [\"v1\"]\n      resources:   [\"customresourcedefinitions\"]\n      operations:  [\"CREATE\", \"UPDATE\"]\n"
  },
  {
    "path": "pkg/gateway/envoy.go",
    "content": "package gateway\n\nimport (\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"k8s.io/klog/v2\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/constants\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n// keep in sync with dynamicControlPlaneConfig\nconst (\n\tproxyConfigPath = \"/home/envoy/envoy.yaml\"\n\tenvoyAdminPort  = 10000\n\n\t// well known dns to reach host from containers\n\t// https://github.com/containerd/nerdctl/issues/747\n\tdockerInternal = \"host.docker.internal\"\n\tlimaInternal   = \"host.lima.internal\"\n)\n\n// https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/configuration-dynamic-control-plane\nconst dynamicControlPlaneConfig = `node:\n  cluster: {{ .Cluster }}\n  id: {{ .ID }}\n\ndynamic_resources:\n  ads_config:\n    api_type: GRPC\n    grpc_services:\n    - envoy_grpc:\n        cluster_name: xds_cluster\n  cds_config:\n    ads: {}\n  lds_config:\n    ads: {}\n\nstatic_resources:\n  clusters:\n  - type: STRICT_DNS\n    typed_extension_protocol_options:\n      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:\n        \"@type\": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions\n        explicit_http_config:\n          http2_protocol_options: {}\n    name: xds_cluster\n    load_assignment:\n      cluster_name: xds_cluster\n      endpoints:\n      - lb_endpoints:\n        - endpoint:\n            address:\n              socket_address:\n                address: {{ .ControlPlaneAddress }}\n                port_value: {{ .ControlPlanePort }}\n        - endpoint:\n            address:\n              socket_address:\n                address: host.docker.internal\n                port_value: {{ .ControlPlanePort }}\n        - endpoint:\n            address:\n              socket_address:\n                address: host.lima.internal\n                port_value: {{ .ControlPlanePort }}\n\nadmin:\n  access_log_path: /dev/stdout\n  address:\n    socket_address:\n      address: 0.0.0.0\n      port_value: {{ .AdminPort }}\n`\n\ntype configData struct {\n\tCluster             string\n\tID                  string\n\tAdminPort           int\n\tControlPlaneAddress string\n\tControlPlanePort    int\n}\n\n// generateEnvoyConfig returns an envoy config generated from config data\nfunc generateEnvoyConfig(data *configData) (string, error) {\n\tif data.Cluster == \"\" ||\n\t\tdata.ID == \"\" ||\n\t\tdata.AdminPort == 0 ||\n\t\tdata.ControlPlaneAddress == \"\" ||\n\t\tdata.ControlPlanePort == 0 {\n\t\treturn \"\", fmt.Errorf(\"missing parameters\")\n\t}\n\n\tt, err := template.New(\"gateway-config\").Parse(dynamicControlPlaneConfig)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to parse config template: %w\", err)\n\t}\n\t// execute the template\n\tvar buff bytes.Buffer\n\terr = t.Execute(&buff, data)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error executing config template: %w\", err)\n\t}\n\treturn buff.String(), nil\n}\n\n// gatewayName name is a unique name for the gateway container\nfunc gatewayName(clusterName, namespace, name string) string {\n\th := sha256.New()\n\t_, err := io.WriteString(h, gatewaySimpleName(clusterName, namespace, name))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\thash := h.Sum(nil)\n\treturn fmt.Sprintf(\"%s-gw-%x\", constants.ContainerPrefix, hash[:6])\n}\n\nfunc gatewaySimpleName(clusterName, namespace, name string) string {\n\treturn clusterName + \"/\" + namespace + \"/\" + name\n}\n\n// createGateway create a docker container with a gateway\nfunc createGateway(clusterName string, nameserver string, localAddress string, localPort int, gateway *gatewayv1.Gateway, enableTunnel bool) error {\n\tname := gatewayName(clusterName, gateway.Namespace, gateway.Name)\n\tsimpleName := gatewaySimpleName(clusterName, gateway.Namespace, gateway.Name)\n\tenvoyConfigData := &configData{\n\t\tID:                  name,\n\t\tCluster:             simpleName,\n\t\tAdminPort:           envoyAdminPort,\n\t\tControlPlaneAddress: localAddress,\n\t\tControlPlanePort:    localPort,\n\t}\n\tdynamicFilesystemConfig, err := generateEnvoyConfig(envoyConfigData)\n\tif err != nil {\n\t\treturn err\n\t}\n\tnetworkName := constants.FixedNetworkName\n\tif n := os.Getenv(\"KIND_EXPERIMENTAL_DOCKER_NETWORK\"); n != \"\" {\n\t\tnetworkName = n\n\t}\n\n\targs := []string{\n\t\t\"--detach\",\n\t\t\"--tty\",\n\t\t\"--user=0\",\n\t\t\"--label\", fmt.Sprintf(\"%s=%s\", constants.NodeCCMLabelKey, clusterName),\n\t\t\"--label\", fmt.Sprintf(\"%s=%s\", constants.GatewayNameLabelKey, simpleName),\n\t\t\"--net\", networkName,\n\t\t\"--dns\", nameserver,\n\t\t\"--init=false\",\n\t\t\"--hostname\", name,\n\t\t\"--privileged\",\n\t\t\"--restart=on-failure\",\n\t\t\"--sysctl=net.ipv4.ip_forward=1\",\n\t\t\"--sysctl=net.ipv4.conf.all.rp_filter=0\",\n\t\t\"--sysctl=net.ipv4.ip_unprivileged_port_start=1\",\n\t}\n\n\t// support to specify addresses\n\t// only the first of each IP family will be used\n\t// listenAddress tracks the host bind address for port publishing: \"0.0.0.0\" for IPv4-only,\n\t// \"::\" for IPv6-only, or \"\" for dual-stack/unspecified (publish on all interfaces).\n\tvar ipv4, ipv6, listenAddress string\n\tfor _, address := range gateway.Spec.Addresses {\n\t\tif address.Type != nil && *address.Type != gatewayv1.IPAddressType {\n\t\t\tcontinue\n\t\t}\n\t\tip, err := netip.ParseAddr(address.Value)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif ip.Is4() {\n\t\t\tif ipv4 == \"\" {\n\t\t\t\tipv4 = address.Value\n\t\t\t\targs = append(args, \"--ip\", ip.String())\n\t\t\t\tif ipv6 == \"\" {\n\t\t\t\t\tlistenAddress = \"0.0.0.0\"\n\t\t\t\t} else {\n\t\t\t\t\tlistenAddress = \"\" // dual-stack\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ip.Is6() {\n\t\t\tif ipv6 == \"\" {\n\t\t\t\tipv6 = address.Value\n\t\t\t\targs = append(args, \"--ip6\", ip.String())\n\t\t\t\tif ipv4 == \"\" {\n\t\t\t\t\tlistenAddress = \"::\"\n\t\t\t\t} else {\n\t\t\t\t\tlistenAddress = \"\" // dual-stack\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\targs = append(args, []string{\n\t\t\"--sysctl=net.ipv6.conf.all.disable_ipv6=0\",\n\t\t\"--sysctl=net.ipv6.conf.all.forwarding=1\",\n\t}...)\n\n\tif enableTunnel ||\n\t\tconfig.DefaultConfig.LoadBalancerConnectivity == config.Portmap {\n\t\t// Forward the Listener Ports to the host so they are accessible on Mac and Windows.\n\t\t// For single IP-family gateways, explicitly bind on the matching listen address to avoid\n\t\t// dual-stack host bindings that cause connection resets in environments where IPv6 is\n\t\t// advertised but not functional end-to-end (e.g. some GitHub Actions runners).\n\t\t// For dual-stack or unspecified gateways, publish without an explicit address.\n\t\t// See https://github.com/kubernetes-sigs/cloud-provider-kind/issues/387\n\t\tfor _, listener := range gateway.Spec.Listeners {\n\t\t\tproto := \"tcp\"\n\t\t\tif listener.Protocol == gatewayv1.UDPProtocolType {\n\t\t\t\tproto = \"udp\"\n\t\t\t}\n\t\t\tif listenAddress != \"\" {\n\t\t\t\thostPortBinding := net.JoinHostPort(listenAddress, fmt.Sprintf(\"%d\", listener.Port))\n\t\t\t\targs = append(args, fmt.Sprintf(\"--publish=%s:%d/%s\", hostPortBinding, listener.Port, proto))\n\t\t\t} else {\n\t\t\t\targs = append(args, fmt.Sprintf(\"--publish=%d/%s\", listener.Port, proto))\n\t\t\t}\n\t\t}\n\t}\n\targs = append(args, \"--publish-all\")\n\n\t// Construct the multi-step command\n\tvar startupCmd strings.Builder\n\tstartupCmd.WriteString(fmt.Sprintf(\"echo -en '%s' > %s && \", dynamicFilesystemConfig, proxyConfigPath))\n\tstartupCmd.WriteString(fmt.Sprintf(\"while true; do envoy -c %s && break; sleep 1; done\", proxyConfigPath))\n\n\targs = append(args, config.DefaultConfig.ProxyImage)\n\tcmd := []string{\"bash\", \"-c\", startupCmd.String()}\n\targs = append(args, cmd...)\n\n\tklog.V(2).Infof(\"creating gateway with parameters: %v\", args)\n\terr = container.Create(name, args)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create containers %s %v: %w\", name, args, err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/gateway/envoy_test.go",
    "content": "package gateway\n\nimport \"testing\"\n\nfunc TestGenerateEnvoyConfigTable(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\tconfigData     *configData\n\t\texpectedConfig string\n\t\twantErr        bool\n\t}{\n\t\t{\n\t\t\tname: \"Default Configuration\",\n\t\t\tconfigData: &configData{\n\t\t\t\tCluster:             \"test-cluster\",\n\t\t\t\tID:                  \"test-id\",\n\t\t\t\tAdminPort:           9000,\n\t\t\t\tControlPlaneAddress: \"192.168.1.10\",\n\t\t\t\tControlPlanePort:    8080,\n\t\t\t},\n\t\t\texpectedConfig: `node:\n  cluster: test-cluster\n  id: test-id\n\ndynamic_resources:\n  ads_config:\n    api_type: GRPC\n    grpc_services:\n    - envoy_grpc:\n        cluster_name: xds_cluster\n  cds_config:\n    ads: {}\n  lds_config:\n    ads: {}\n\nstatic_resources:\n  clusters:\n  - type: STRICT_DNS\n    typed_extension_protocol_options:\n      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:\n        \"@type\": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions\n        explicit_http_config:\n          http2_protocol_options: {}\n    name: xds_cluster\n    load_assignment:\n      cluster_name: xds_cluster\n      endpoints:\n      - lb_endpoints:\n        - endpoint:\n            address:\n              socket_address:\n                address: 192.168.1.10\n                port_value: 8080\n        - endpoint:\n            address:\n              socket_address:\n                address: host.docker.internal\n                port_value: 8080\n        - endpoint:\n            address:\n              socket_address:\n                address: host.lima.internal\n                port_value: 8080\n\nadmin:\n  access_log_path: /dev/stdout\n  address:\n    socket_address:\n      address: 0.0.0.0\n      port_value: 9000\n`,\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Different Ports and Addresses\",\n\t\t\tconfigData: &configData{\n\t\t\t\tCluster:             \"another-cluster\",\n\t\t\t\tID:                  \"instance-01\",\n\t\t\t\tAdminPort:           12345,\n\t\t\t\tControlPlaneAddress: \"10.0.1.5\",\n\t\t\t\tControlPlanePort:    50051,\n\t\t\t},\n\t\t\texpectedConfig: `node:\n  cluster: another-cluster\n  id: instance-01\n\ndynamic_resources:\n  ads_config:\n    api_type: GRPC\n    grpc_services:\n    - envoy_grpc:\n        cluster_name: xds_cluster\n  cds_config:\n    ads: {}\n  lds_config:\n    ads: {}\n\nstatic_resources:\n  clusters:\n  - type: STRICT_DNS\n    typed_extension_protocol_options:\n      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:\n        \"@type\": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions\n        explicit_http_config:\n          http2_protocol_options: {}\n    name: xds_cluster\n    load_assignment:\n      cluster_name: xds_cluster\n      endpoints:\n      - lb_endpoints:\n        - endpoint:\n            address:\n              socket_address:\n                address: 10.0.1.5\n                port_value: 50051\n        - endpoint:\n            address:\n              socket_address:\n                address: host.docker.internal\n                port_value: 50051\n        - endpoint:\n            address:\n              socket_address:\n                address: host.lima.internal\n                port_value: 50051\n\nadmin:\n  access_log_path: /dev/stdout\n  address:\n    socket_address:\n      address: 0.0.0.0\n      port_value: 12345\n`,\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Empty Cluster and ID\",\n\t\t\tconfigData: &configData{\n\t\t\t\tCluster:             \"\",\n\t\t\t\tID:                  \"\",\n\t\t\t\tAdminPort:           80,\n\t\t\t\tControlPlaneAddress: \"localhost\",\n\t\t\t\tControlPlanePort:    8080,\n\t\t\t},\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tconfig, err := generateEnvoyConfig(tt.configData)\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"generateEnvoyConfig() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif config != tt.expectedConfig {\n\t\t\t\tt.Errorf(\"generateEnvoyConfig() got = \\n%v\\nwant = \\n%v\", config, tt.expectedConfig)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/gateway/gateway.go",
    "content": "package gateway\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/types/known/durationpb\"\n\n\tclusterv3 \"github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3\"\n\tcorev3 \"github.com/envoyproxy/go-control-plane/envoy/config/core/v3\"\n\tendpointv3 \"github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3\"\n\tlistenerv3 \"github.com/envoyproxy/go-control-plane/envoy/config/listener/v3\"\n\troutev3 \"github.com/envoyproxy/go-control-plane/envoy/config/route/v3\"\n\ttypev3 \"github.com/envoyproxy/go-control-plane/envoy/type/v3\"\n\tenvoyproxytypes \"github.com/envoyproxy/go-control-plane/pkg/cache/types\"\n\tcachev3 \"github.com/envoyproxy/go-control-plane/pkg/cache/v3\"\n\tresourcev3 \"github.com/envoyproxy/go-control-plane/pkg/resource/v3\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/conversion\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/client-go/tools/cache\"\n\t\"k8s.io/client-go/util/retry\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/ptr\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\nvar (\n\tCloudProviderSupportedKinds = sets.New[gatewayv1.Kind](\n\t\t\"HTTPRoute\",\n\t\t// \"GRPCRoute\",\n\t)\n)\n\nfunc (c *Controller) syncGateway(ctx context.Context, key string) error {\n\tstartTime := time.Now()\n\tdefer func() {\n\t\tklog.V(2).Infof(\"Finished syncing gateway %q (%v)\", key, time.Since(startTime))\n\t}()\n\n\tnamespace, name, err := cache.SplitMetaNamespaceKey(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tgw, err := c.gatewayLister.Gateways(namespace).Get(name)\n\tif apierrors.IsNotFound(err) {\n\t\tklog.V(2).Infof(\"Gateway %s has been deleted, cleaning up resources\", key)\n\t\treturn c.deleteGatewayResources(ctx, name, namespace)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get gateway %s: %w\", key, err)\n\t}\n\n\tif gw.Spec.GatewayClassName != GWClassName {\n\t\tklog.V(2).Infof(\"Gateway %s is not for this controller, ignoring\", key)\n\t\treturn nil\n\t}\n\n\tcontainerName := gatewayName(c.clusterName, namespace, name)\n\tklog.Infof(\"Syncing Gateway %s, container %s\", key, containerName)\n\n\terr = c.ensureGatewayContainer(ctx, gw)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to ensure gateway container %s: %w\", containerName, err)\n\t}\n\n\tnewGw := gw.DeepCopy()\n\tipv4, ipv6, err := container.IPs(containerName)\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"failed to get container details\") {\n\t\t\treturn err\n\t\t}\n\t\treturn err\n\t}\n\n\tnewGw.Status.Addresses = []gatewayv1.GatewayStatusAddress{}\n\tif net.ParseIP(ipv4) != nil {\n\t\tnewGw.Status.Addresses = append(newGw.Status.Addresses,\n\t\t\tgatewayv1.GatewayStatusAddress{\n\t\t\t\tType:  ptr.To(gatewayv1.IPAddressType),\n\t\t\t\tValue: ipv4,\n\t\t\t})\n\t}\n\tif net.ParseIP(ipv6) != nil {\n\t\tnewGw.Status.Addresses = append(newGw.Status.Addresses,\n\t\t\tgatewayv1.GatewayStatusAddress{\n\t\t\t\tType:  ptr.To(gatewayv1.IPAddressType),\n\t\t\t\tValue: ipv6,\n\t\t\t})\n\t}\n\n\t// Get the desired state\n\tenvoyResources, listenerStatuses, httpRouteStatuses, grpcRouteStatuses := c.buildEnvoyResourcesForGateway(newGw)\n\n\t// Apply the desired state to the data plane (Envoy).\n\tnewGw.Status.Listeners = listenerStatuses\n\terr = c.UpdateXDSServer(ctx, containerName, envoyResources)\n\n\t// forward traffic from the host on Mac and Windows\n\tif c.tunnelManager != nil {\n\t\terr := c.tunnelManager.SetupTunnels(containerName)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"failed to set up tunnels for gateway %s: %v\", key, err)\n\t\t}\n\t}\n\n\t// Calculate and set the Gateway's own status conditions based on the build results.\n\tsetGatewayConditions(newGw, listenerStatuses, err)\n\n\tif !reflect.DeepEqual(gw.Status, newGw.Status) {\n\t\t_, err := c.gwClient.GatewayV1().Gateways(newGw.Namespace).UpdateStatus(ctx, newGw, metav1.UpdateOptions{})\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to update gateway status: %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn c.updateRouteStatuses(ctx, httpRouteStatuses, grpcRouteStatuses)\n}\n\n// Main State Calculation Function\nfunc (c *Controller) buildEnvoyResourcesForGateway(gateway *gatewayv1.Gateway) (\n\tmap[resourcev3.Type][]envoyproxytypes.Resource,\n\t[]gatewayv1.ListenerStatus,\n\tmap[types.NamespacedName][]gatewayv1.RouteParentStatus, // HTTPRoutes\n\tmap[types.NamespacedName][]gatewayv1.RouteParentStatus, // GRPCRoutes\n) {\n\n\thttpRouteStatuses := make(map[types.NamespacedName][]gatewayv1.RouteParentStatus)\n\tgrpcRouteStatuses := make(map[types.NamespacedName][]gatewayv1.RouteParentStatus)\n\troutesByListener := make(map[gatewayv1.SectionName][]*gatewayv1.HTTPRoute)\n\n\t// Validate all HTTPRoutes against this Gateway\n\tallHTTPRoutesForGateway := c.getHTTPRoutesForGateway(gateway)\n\tfor _, httpRoute := range allHTTPRoutesForGateway {\n\t\tkey := types.NamespacedName{Name: httpRoute.Name, Namespace: httpRoute.Namespace}\n\t\tparentStatuses, acceptingListeners := c.validateHTTPRoute(gateway, httpRoute)\n\n\t\t// Store the definitive status for the route.\n\t\tif len(parentStatuses) > 0 {\n\t\t\thttpRouteStatuses[key] = parentStatuses\n\t\t}\n\t\t// If the route was accepted, associate it with the listeners that accepted it.\n\t\tif len(acceptingListeners) > 0 {\n\t\t\t// Associate the accepted route with the listeners that will handle it.\n\t\t\t// Use a set to prevent adding a route multiple times to the same listener.\n\t\t\tprocessedListeners := make(map[gatewayv1.SectionName]bool)\n\t\t\tfor _, listener := range acceptingListeners {\n\t\t\t\tif _, ok := processedListeners[listener.Name]; !ok {\n\t\t\t\t\troutesByListener[listener.Name] = append(routesByListener[listener.Name], httpRoute)\n\t\t\t\t\tprocessedListeners[listener.Name] = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build Envoy config using only the pre-validated and accepted routes\n\tenvoyRoutes := []envoyproxytypes.Resource{}\n\tenvoyClusters := make(map[string]envoyproxytypes.Resource)\n\tallListenerStatuses := make(map[gatewayv1.SectionName]gatewayv1.ListenerStatus)\n\t// Aggregate Listeners by Port\n\tlistenersByPort := make(map[gatewayv1.PortNumber][]gatewayv1.Listener)\n\tfor _, listener := range gateway.Spec.Listeners {\n\t\tlistenersByPort[listener.Port] = append(listenersByPort[listener.Port], listener)\n\t}\n\n\t// validate listeners that may reuse the same port\n\tlistenerValidationConditions := c.validateListeners(gateway)\n\n\tfinalEnvoyListeners := []envoyproxytypes.Resource{}\n\t// Process Listeners by Port\n\tfor port, listeners := range listenersByPort {\n\t\t// This slice will hold the filter chains.\n\t\tvar filterChains []*listenerv3.FilterChain\n\t\t// Prepare to collect ALL virtual hosts for this port into a single list.\n\t\tvirtualHostsForPort := make(map[string]*routev3.VirtualHost)\n\t\trouteName := fmt.Sprintf(\"route-%d\", port)\n\n\t\t// All these listeners have the same port\n\t\tfor _, listener := range listeners {\n\t\t\tvar attachedRoutes int32\n\t\t\tlistenerStatus := gatewayv1.ListenerStatus{\n\t\t\t\tName:           gatewayv1.SectionName(listener.Name),\n\t\t\t\tSupportedKinds: []gatewayv1.RouteGroupKind{},\n\t\t\t\tConditions:     []metav1.Condition{},\n\t\t\t\tAttachedRoutes: 0,\n\t\t\t}\n\t\t\t// Find old status to preserve condition timestamps\n\t\t\tfor _, oldStatus := range gateway.Status.Listeners {\n\t\t\t\tif oldStatus.Name == listener.Name {\n\t\t\t\t\tlistenerStatus.Conditions = oldStatus.Conditions // Copy old conditions\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply pre-calculated validation conditions\n\t\t\tif validationConds, ok := listenerValidationConditions[listener.Name]; ok {\n\t\t\t\tfor _, cond := range validationConds {\n\t\t\t\t\tmeta.SetStatusCondition(&listenerStatus.Conditions, cond)\n\t\t\t\t}\n\t\t\t}\n\t\t\tsupportedKinds, allKindsValid := getSupportedKinds(listener)\n\t\t\tlistenerStatus.SupportedKinds = supportedKinds\n\n\t\t\tif !allKindsValid {\n\t\t\t\tmeta.SetStatusCondition(&listenerStatus.Conditions, metav1.Condition{\n\t\t\t\t\tType:               string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\tStatus:             metav1.ConditionFalse,\n\t\t\t\t\tReason:             string(gatewayv1.ListenerReasonInvalidRouteKinds),\n\t\t\t\t\tMessage:            \"Invalid route kinds specified in allowedRoutes\",\n\t\t\t\t\tObservedGeneration: gateway.Generation,\n\t\t\t\t})\n\t\t\t\tallListenerStatuses[listener.Name] = listenerStatus\n\t\t\t\tcontinue // Stop processing this invalid listener\n\t\t\t}\n\n\t\t\tisConflicted := meta.IsStatusConditionTrue(listenerStatus.Conditions, string(gatewayv1.ListenerConditionConflicted))\n\t\t\t// If the listener is conflicted set its status and skip Envoy config generation.\n\t\t\tif isConflicted {\n\t\t\t\tallListenerStatuses[listener.Name] = listenerStatus\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If there are not references issues then set it to tru\n\t\t\tif !meta.IsStatusConditionFalse(listenerStatus.Conditions, string(gatewayv1.ListenerConditionResolvedRefs)) {\n\t\t\t\tmeta.SetStatusCondition(&listenerStatus.Conditions, metav1.Condition{\n\t\t\t\t\tType:               string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\tStatus:             metav1.ConditionTrue,\n\t\t\t\t\tReason:             string(gatewayv1.ListenerReasonResolvedRefs),\n\t\t\t\t\tMessage:            \"All references resolved\",\n\t\t\t\t\tObservedGeneration: gateway.Generation,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tswitch listener.Protocol {\n\t\t\tcase gatewayv1.HTTPProtocolType, gatewayv1.HTTPSProtocolType:\n\t\t\t\t// Process HTTPRoutes\n\t\t\t\t// Get the routes that were pre-validated for this specific listener.\n\t\t\t\tfor _, httpRoute := range routesByListener[listener.Name] {\n\t\t\t\t\troutes, validBackendRefs, resolvedRefsCondition := translateHTTPRouteToEnvoyRoutes(httpRoute, c.serviceLister, c.referenceGrantLister)\n\n\t\t\t\t\tkey := types.NamespacedName{Name: httpRoute.Name, Namespace: httpRoute.Namespace}\n\t\t\t\t\tcurrentParentStatuses := httpRouteStatuses[key]\n\t\t\t\t\tfor i := range currentParentStatuses {\n\t\t\t\t\t\t// Only add the ResolvedRefs condition if the parent was Accepted.\n\t\t\t\t\t\tif meta.IsStatusConditionTrue(currentParentStatuses[i].Conditions, string(gatewayv1.RouteConditionAccepted)) {\n\t\t\t\t\t\t\tmeta.SetStatusCondition(&currentParentStatuses[i].Conditions, resolvedRefsCondition)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\thttpRouteStatuses[key] = currentParentStatuses\n\n\t\t\t\t\t// Create the necessary Envoy Cluster resources from the valid backends.\n\t\t\t\t\tfor _, backendRef := range validBackendRefs {\n\t\t\t\t\t\tcluster, err := c.translateBackendRefToCluster(httpRoute.Namespace, backendRef)\n\t\t\t\t\t\tif err == nil && cluster != nil {\n\t\t\t\t\t\t\tif _, exists := envoyClusters[cluster.Name]; !exists {\n\t\t\t\t\t\t\t\tenvoyClusters[cluster.Name] = cluster\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Aggregate Envoy routes into VirtualHosts.\n\t\t\t\t\tif routes != nil {\n\t\t\t\t\t\tattachedRoutes++\n\t\t\t\t\t\t// Get the domain for this listener's VirtualHost.\n\t\t\t\t\t\tvhostDomains := getIntersectingHostnames(listener, httpRoute.Spec.Hostnames)\n\t\t\t\t\t\tfor _, domain := range vhostDomains {\n\t\t\t\t\t\t\tvh, ok := virtualHostsForPort[domain]\n\t\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\t\tvh = &routev3.VirtualHost{\n\t\t\t\t\t\t\t\t\tName:    fmt.Sprintf(\"%s-vh-%d-%s\", gateway.Name, port, domain),\n\t\t\t\t\t\t\t\t\tDomains: []string{domain},\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tvirtualHostsForPort[domain] = vh\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvh.Routes = append(vh.Routes, routes...)\n\t\t\t\t\t\t\tklog.V(4).Infof(\"created VirtualHost %s for listener %s with domain %s\", vh.Name, listener.\n\t\t\t\t\t\t\t\tName, domain)\n\t\t\t\t\t\t\tif klog.V(4).Enabled() {\n\t\t\t\t\t\t\t\tfor _, route := range routes {\n\t\t\t\t\t\t\t\t\tklog.Infof(\"adding route %s to VirtualHost %s\", route.Name, vh.Name)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// TODO: Process GRPCRoutes\n\n\t\t\tdefault:\n\t\t\t\tklog.Warningf(\"Unsupported listener protocol for route processing: %s\", listener.Protocol)\n\t\t\t}\n\n\t\t\tvhSlice := make([]*routev3.VirtualHost, 0, len(virtualHostsForPort))\n\t\t\tfor _, vh := range virtualHostsForPort {\n\t\t\t\tvhSlice = append(vhSlice, vh)\n\t\t\t}\n\n\t\t\tfilterChain, err := c.translateListenerToFilterChain(gateway, listener, vhSlice, routeName)\n\t\t\tif err != nil {\n\t\t\t\tmeta.SetStatusCondition(&listenerStatus.Conditions, metav1.Condition{\n\t\t\t\t\tType:               string(gatewayv1.ListenerConditionProgrammed),\n\t\t\t\t\tStatus:             metav1.ConditionFalse,\n\t\t\t\t\tReason:             string(gatewayv1.ListenerReasonInvalid),\n\t\t\t\t\tMessage:            fmt.Sprintf(\"Failed to program listener: %v\", err),\n\t\t\t\t\tObservedGeneration: gateway.Generation,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tmeta.SetStatusCondition(&listenerStatus.Conditions, metav1.Condition{\n\t\t\t\t\tType:               string(gatewayv1.ListenerConditionProgrammed),\n\t\t\t\t\tStatus:             metav1.ConditionTrue,\n\t\t\t\t\tReason:             string(gatewayv1.ListenerReasonProgrammed),\n\t\t\t\t\tMessage:            \"Listener is programmed\",\n\t\t\t\t\tObservedGeneration: gateway.Generation,\n\t\t\t\t})\n\n\t\t\t\tfilterChains = append(filterChains, filterChain)\n\t\t\t}\n\n\t\t\tlistenerStatus.AttachedRoutes = attachedRoutes\n\t\t\tmeta.SetStatusCondition(&listenerStatus.Conditions, metav1.Condition{\n\t\t\t\tType:               string(gatewayv1.ListenerConditionAccepted),\n\t\t\t\tStatus:             metav1.ConditionTrue,\n\t\t\t\tReason:             string(gatewayv1.ListenerReasonAccepted),\n\t\t\t\tMessage:            \"Listener is valid\",\n\t\t\t\tObservedGeneration: gateway.Generation,\n\t\t\t})\n\t\t\tallListenerStatuses[listener.Name] = listenerStatus\n\t\t}\n\n\t\tallVirtualHosts := make([]*routev3.VirtualHost, 0, len(virtualHostsForPort))\n\t\tfor _, vh := range virtualHostsForPort {\n\t\t\tsortRoutes(vh.Routes)\n\t\t\tallVirtualHosts = append(allVirtualHosts, vh)\n\t\t}\n\n\t\t// now aggregate all the listeners on the same port\n\t\trouteConfig := &routev3.RouteConfiguration{\n\t\t\tName:                     routeName,\n\t\t\tVirtualHosts:             allVirtualHosts,\n\t\t\tIgnorePortInHostMatching: true, // tricky to figure out thanks to howardjohn\n\t\t}\n\t\tenvoyRoutes = append(envoyRoutes, routeConfig)\n\n\t\tif len(filterChains) > 0 {\n\t\t\tenvoyListener := &listenerv3.Listener{\n\t\t\t\tName:            fmt.Sprintf(\"listener-%d\", port),\n\t\t\t\tAddress:         createEnvoyAddress(uint32(port)),\n\t\t\t\tFilterChains:    filterChains,\n\t\t\t\tListenerFilters: createListenerFilters(),\n\t\t\t}\n\t\t\t// If this is plain HTTP, we must now create exactly ONE default filter chain.\n\t\t\t// Use first listener as a template\n\t\t\t// For HTTPS, we create one filter chain per listener because they have unique\n\t\t\t// SNI matches and TLS settings.\n\t\t\tif listeners[0].Protocol == gatewayv1.HTTPProtocolType {\n\t\t\t\tfilterChain, _ := c.translateListenerToFilterChain(gateway, listeners[0], allVirtualHosts, routeName)\n\t\t\t\tenvoyListener.FilterChains = []*listenerv3.FilterChain{filterChain}\n\t\t\t}\n\t\t\tfinalEnvoyListeners = append(finalEnvoyListeners, envoyListener)\n\t\t}\n\t}\n\n\tclustersSlice := make([]envoyproxytypes.Resource, 0, len(envoyClusters))\n\tfor _, cluster := range envoyClusters {\n\t\tclustersSlice = append(clustersSlice, cluster)\n\t}\n\n\torderedStatuses := make([]gatewayv1.ListenerStatus, len(gateway.Spec.Listeners))\n\tfor i, listener := range gateway.Spec.Listeners {\n\t\torderedStatuses[i] = allListenerStatuses[listener.Name]\n\t}\n\n\treturn map[resourcev3.Type][]envoyproxytypes.Resource{\n\t\t\tresourcev3.ListenerType: finalEnvoyListeners,\n\t\t\tresourcev3.RouteType:    envoyRoutes,\n\t\t\tresourcev3.ClusterType:  clustersSlice,\n\t\t}, orderedStatuses,\n\t\thttpRouteStatuses,\n\t\tgrpcRouteStatuses\n}\n\nfunc getSupportedKinds(listener gatewayv1.Listener) ([]gatewayv1.RouteGroupKind, bool) {\n\tsupportedKinds := []gatewayv1.RouteGroupKind{}\n\tallKindsValid := true\n\tgroupName := gatewayv1.Group(gatewayv1.GroupName)\n\n\tif listener.AllowedRoutes != nil && len(listener.AllowedRoutes.Kinds) > 0 {\n\t\tfor _, kind := range listener.AllowedRoutes.Kinds {\n\t\t\tif (kind.Group == nil || *kind.Group == groupName) && CloudProviderSupportedKinds.Has(kind.Kind) {\n\t\t\t\tsupportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{\n\t\t\t\t\tGroup: &groupName,\n\t\t\t\t\tKind:  kind.Kind,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tallKindsValid = false\n\t\t\t}\n\t\t}\n\t} else if listener.Protocol == gatewayv1.HTTPProtocolType || listener.Protocol == gatewayv1.HTTPSProtocolType {\n\t\tfor _, kind := range CloudProviderSupportedKinds.UnsortedList() {\n\t\t\tsupportedKinds = append(supportedKinds,\n\t\t\t\tgatewayv1.RouteGroupKind{\n\t\t\t\t\tGroup: &groupName,\n\t\t\t\t\tKind:  kind,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\treturn supportedKinds, allKindsValid\n}\n\nvar semanticIgnoreLastTransitionTime = conversion.EqualitiesOrDie(\n\tfunc(a, b metav1.Condition) bool {\n\t\ta.LastTransitionTime = metav1.Time{}\n\t\tb.LastTransitionTime = metav1.Time{}\n\t\treturn a == b\n\t},\n)\n\nfunc (c *Controller) updateRouteStatuses(\n\tctx context.Context,\n\thttpRouteStatuses map[types.NamespacedName][]gatewayv1.RouteParentStatus,\n\tgrpcRouteStatuses map[types.NamespacedName][]gatewayv1.RouteParentStatus,\n) error {\n\tvar errGroup []error\n\n\t// --- Process HTTPRoutes ---\n\tfor key, desiredParentStatuses := range httpRouteStatuses {\n\t\terr := retry.RetryOnConflict(retry.DefaultRetry, func() error {\n\t\t\t// GET the latest version of the route from the cache.\n\t\t\toriginalRoute, err := c.httprouteLister.HTTPRoutes(key.Namespace).Get(key.Name)\n\t\t\tif apierrors.IsNotFound(err) {\n\t\t\t\t// Route has been deleted, nothing to do.\n\t\t\t\treturn nil\n\t\t\t} else if err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Create a mutable copy to work with.\n\t\t\trouteToUpdate := originalRoute.DeepCopy()\n\t\t\trouteToUpdate.Status.Parents = desiredParentStatuses\n\n\t\t\t// Only make an API call if the status has actually changed.\n\t\t\tif !semanticIgnoreLastTransitionTime.DeepEqual(originalRoute.Status, routeToUpdate.Status) {\n\t\t\t\t_, updateErr := c.gwClient.GatewayV1().HTTPRoutes(routeToUpdate.Namespace).UpdateStatus(ctx, routeToUpdate, metav1.UpdateOptions{})\n\t\t\t\treturn updateErr\n\t\t\t}\n\n\t\t\t// Status is already up-to-date.\n\t\t\treturn nil\n\t\t})\n\n\t\tif err != nil {\n\t\t\terrGroup = append(errGroup, fmt.Errorf(\"failed to update status for HTTPRoute %s: %w\", key, err))\n\t\t}\n\t}\n\n\t// TODO: Process GRPCRoutes (repeat the same logic)\n\n\treturn errors.Join(errGroup...)\n}\n\n// getHTTPRoutesForGateway returns all HTTPRoutes that have a ParentRef pointing to the specified Gateway.\nfunc (c *Controller) getHTTPRoutesForGateway(gw *gatewayv1.Gateway) []*gatewayv1.HTTPRoute {\n\tvar matchingRoutes []*gatewayv1.HTTPRoute\n\tallRoutes, err := c.httprouteLister.List(labels.Everything())\n\tif err != nil {\n\t\tklog.Errorf(\"failed to list HTTPRoutes: %v\", err)\n\t\treturn matchingRoutes\n\t}\n\n\tfor _, route := range allRoutes {\n\t\tfor _, parentRef := range route.Spec.ParentRefs {\n\t\t\t// Check if the ParentRef targets the Gateway, defaulting to the route's namespace.\n\t\t\trefNamespace := route.Namespace\n\t\t\tif parentRef.Namespace != nil {\n\t\t\t\trefNamespace = string(*parentRef.Namespace)\n\t\t\t}\n\t\t\tif parentRef.Name == gatewayv1.ObjectName(gw.Name) && refNamespace == gw.Namespace {\n\t\t\t\tmatchingRoutes = append(matchingRoutes, route)\n\t\t\t\tbreak // Found a matching ref for this gateway, no need to check others.\n\t\t\t}\n\t\t}\n\t}\n\treturn matchingRoutes\n}\n\n// validateHTTPRoute is the definitive validation function. It iterates through all\n// parentRefs of an HTTPRoute and generates a complete RouteParentStatus for each one\n// that targets the specified Gateway. It also returns a slice of all listeners\n// that ended up accepting the route.\nfunc (c *Controller) validateHTTPRoute(\n\tgateway *gatewayv1.Gateway,\n\thttpRoute *gatewayv1.HTTPRoute,\n) ([]gatewayv1.RouteParentStatus, []gatewayv1.Listener) {\n\n\tvar parentStatuses []gatewayv1.RouteParentStatus\n\t// Use a map to collect a unique set of listeners that accepted the route.\n\tacceptedListenerSet := make(map[gatewayv1.SectionName]gatewayv1.Listener)\n\n\t// --- Determine the ResolvedRefs status for the entire Route first. ---\n\t// This is a property of the route itself, independent of any parent.\n\tresolvedRefsCondition := metav1.Condition{\n\t\tType:               string(gatewayv1.RouteConditionResolvedRefs),\n\t\tObservedGeneration: httpRoute.Generation,\n\t}\n\tif c.areBackendsValid(httpRoute) {\n\t\tresolvedRefsCondition.Status = metav1.ConditionTrue\n\t\tresolvedRefsCondition.Reason = string(gatewayv1.RouteReasonResolvedRefs)\n\t\tresolvedRefsCondition.Message = \"All backend references have been resolved.\"\n\t} else {\n\t\tresolvedRefsCondition.Status = metav1.ConditionFalse\n\t\tresolvedRefsCondition.Reason = string(gatewayv1.RouteReasonBackendNotFound)\n\t\tresolvedRefsCondition.Message = \"One or more backend references could not be found.\"\n\t}\n\n\t// --- Iterate over EACH ParentRef in the HTTPRoute ---\n\tfor _, parentRef := range httpRoute.Spec.ParentRefs {\n\t\t// We only care about refs that target our current Gateway.\n\t\trefNamespace := httpRoute.Namespace\n\t\tif parentRef.Namespace != nil {\n\t\t\trefNamespace = string(*parentRef.Namespace)\n\t\t}\n\t\tif parentRef.Name != gatewayv1.ObjectName(gateway.Name) || refNamespace != gateway.Namespace {\n\t\t\tcontinue // This ref is for another Gateway.\n\t\t}\n\n\t\t// This ref targets our Gateway. We MUST generate a status for it.\n\t\tvar listenersForThisRef []gatewayv1.Listener\n\t\trejectionReason := gatewayv1.RouteReasonNoMatchingParent\n\n\t\t// --- Find all listeners on the Gateway that match this specific parentRef ---\n\t\tfor _, listener := range gateway.Spec.Listeners {\n\t\t\tsectionNameMatches := (parentRef.SectionName == nil) || (*parentRef.SectionName == listener.Name)\n\t\t\tportMatches := (parentRef.Port == nil) || (*parentRef.Port == listener.Port)\n\n\t\t\tif sectionNameMatches && portMatches {\n\t\t\t\t// The listener matches the ref. Now check if the listener's policy (e.g., hostname) allows it.\n\t\t\t\tif !isAllowedByListener(gateway, listener, httpRoute, c.namespaceLister) {\n\t\t\t\t\trejectionReason = gatewayv1.RouteReasonNotAllowedByListeners\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif !isAllowedByHostname(listener, httpRoute) {\n\t\t\t\t\trejectionReason = gatewayv1.RouteReasonNoMatchingListenerHostname\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tlistenersForThisRef = append(listenersForThisRef, listener)\n\t\t\t}\n\t\t}\n\n\t\t// --- Build the final status for this ParentRef ---\n\t\tstatus := gatewayv1.RouteParentStatus{\n\t\t\tParentRef:      parentRef,\n\t\t\tControllerName: controllerName,\n\t\t\tConditions:     []metav1.Condition{},\n\t\t}\n\n\t\t// Create the 'Accepted' condition based on the listener validation.\n\t\tacceptedCondition := metav1.Condition{\n\t\t\tType:               string(gatewayv1.RouteConditionAccepted),\n\t\t\tObservedGeneration: httpRoute.Generation,\n\t\t}\n\n\t\tif len(listenersForThisRef) == 0 {\n\t\t\tacceptedCondition.Status = metav1.ConditionFalse\n\t\t\tacceptedCondition.Reason = string(rejectionReason)\n\t\t\tacceptedCondition.Message = \"No listener matched the parentRef.\"\n\t\t\tif rejectionReason == gatewayv1.RouteReasonNotAllowedByListeners {\n\t\t\t\tacceptedCondition.Message = \"Route is not allowed by a listener's policy.\"\n\t\t\t} else {\n\t\t\t\tacceptedCondition.Message = \"The route's hostnames do not match any listener hostnames.\"\n\t\t\t}\n\t\t} else {\n\t\t\tacceptedCondition.Status = metav1.ConditionTrue\n\t\t\tacceptedCondition.Reason = string(gatewayv1.RouteReasonAccepted)\n\t\t\tacceptedCondition.Message = \"Route is accepted.\"\n\t\t\tfor _, l := range listenersForThisRef {\n\t\t\t\tacceptedListenerSet[l.Name] = l\n\t\t\t}\n\t\t}\n\n\t\t// --- 4. Combine the two independent conditions into the final status. ---\n\t\tmeta.SetStatusCondition(&status.Conditions, acceptedCondition)\n\t\tmeta.SetStatusCondition(&status.Conditions, resolvedRefsCondition)\n\n\t\tparentStatuses = append(parentStatuses, status)\n\t}\n\n\tvar allAcceptingListeners []gatewayv1.Listener\n\tfor _, l := range acceptedListenerSet {\n\t\tallAcceptingListeners = append(allAcceptingListeners, l)\n\t}\n\n\treturn parentStatuses, allAcceptingListeners\n}\n\n// areBackendsValid is a helper extracted from the original validate function.\nfunc (c *Controller) areBackendsValid(httpRoute *gatewayv1.HTTPRoute) bool {\n\tfor _, rule := range httpRoute.Spec.Rules {\n\t\tif ruleHasRedirectFilter(rule) {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, backendRef := range rule.BackendRefs {\n\t\t\tns := httpRoute.Namespace\n\t\t\tif backendRef.Namespace != nil {\n\t\t\t\tns = string(*backendRef.Namespace)\n\t\t\t}\n\t\t\tif _, err := c.serviceLister.Services(ns).Get(string(backendRef.Name)); err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// Helper to check for redirect filters\nfunc ruleHasRedirectFilter(rule gatewayv1.HTTPRouteRule) bool {\n\tfor _, filter := range rule.Filters {\n\t\tif filter.Type == gatewayv1.HTTPRouteFilterRequestRedirect {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Controller) translateBackendRefToCluster(defaultNamespace string, backendRef gatewayv1.BackendRef) (*clusterv3.Cluster, error) {\n\tns := defaultNamespace\n\tif backendRef.Namespace != nil {\n\t\tns = string(*backendRef.Namespace)\n\t}\n\tservice, err := c.serviceLister.Services(ns).Get(string(backendRef.Name))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not find service %s/%s: %w\", ns, backendRef.Name, err)\n\t}\n\n\tclusterName, err := backendRefToClusterName(defaultNamespace, backendRef)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Create the base cluster configuration.\n\tcluster := &clusterv3.Cluster{\n\t\tName:           clusterName,\n\t\tConnectTimeout: durationpb.New(5 * time.Second),\n\t\tCommonLbConfig: &clusterv3.Cluster_CommonLbConfig{\n\t\t\tHealthyPanicThreshold: &typev3.Percent{\n\t\t\t\tValue: 0,\n\t\t\t},\n\t\t},\n\t}\n\n\tif service.Spec.ClusterIP == corev1.ClusterIPNone {\n\t\t// Use STRICT_DNS discovery and the service's FQDN.\n\t\tcluster.ClusterDiscoveryType = &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STRICT_DNS}\n\t\t// Construct the FQDN for the service.\n\t\tfqdn := fmt.Sprintf(\"%s.%s.svc.cluster.local\", service.Name, service.Namespace)\n\t\t// Get the port of the endpoints.\n\t\ttargetPort := 0\n\t\tfor _, port := range service.Spec.Ports {\n\t\t\tif port.Port == int32(*backendRef.Port) {\n\t\t\t\ttargetPort = int(port.TargetPort.IntVal)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif targetPort == 0 {\n\t\t\treturn nil, fmt.Errorf(\"could not find port %d in service %s/%s\", *backendRef.Port, service.Namespace, service.Name)\n\t\t}\n\t\tcluster.LoadAssignment = createClusterLoadAssignment(clusterName, fqdn, uint32(targetPort))\n\t} else {\n\t\t// Use STATIC discovery with the service's ClusterIP.\n\t\tcluster.ClusterDiscoveryType = &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}\n\t\tcluster.LoadAssignment = createClusterLoadAssignment(clusterName, service.Spec.ClusterIP, uint32(*backendRef.Port))\n\t}\n\n\treturn cluster, nil\n}\n\nfunc (c *Controller) deleteGatewayResources(ctx context.Context, name, namespace string) error {\n\tklog.Infof(\"Deleting resources for Gateway: %s/%s\", namespace, name)\n\tcontainerName := gatewayName(c.clusterName, namespace, name)\n\n\tc.xdsVersion.Add(1)\n\tversion := fmt.Sprintf(\"%d\", c.xdsVersion.Load())\n\n\tsnapshot, err := cachev3.NewSnapshot(version, map[resourcev3.Type][]envoyproxytypes.Resource{\n\t\tresourcev3.ListenerType: {},\n\t\tresourcev3.RouteType:    {},\n\t\tresourcev3.ClusterType:  {},\n\t\tresourcev3.EndpointType: {},\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create empty snapshot for deleted gateway %s: %w\", name, err)\n\t}\n\tif err := c.xdscache.SetSnapshot(ctx, containerName, snapshot); err != nil {\n\t\treturn fmt.Errorf(\"failed to set empty snapshot for deleted gateway %s: %w\", name, err)\n\t}\n\n\tif c.tunnelManager != nil {\n\t\terr := c.tunnelManager.RemoveTunnels(containerName)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"failed to remove tunnels for deleted gateway %s: %v\", name, err)\n\t\t}\n\t}\n\n\tif err := container.Delete(containerName); err != nil {\n\t\treturn fmt.Errorf(\"failed to delete container for gateway %s: %v\", name, err)\n\t}\n\n\tklog.Infof(\"Successfully cleared resources for deleted Gateway: %s\", name)\n\treturn nil\n}\n\nfunc createClusterLoadAssignment(clusterName, serviceHost string, servicePort uint32) *endpointv3.ClusterLoadAssignment {\n\treturn &endpointv3.ClusterLoadAssignment{\n\t\tClusterName: clusterName,\n\t\tEndpoints: []*endpointv3.LocalityLbEndpoints{\n\t\t\t{\n\t\t\t\tLbEndpoints: []*endpointv3.LbEndpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tHostIdentifier: &endpointv3.LbEndpoint_Endpoint{\n\t\t\t\t\t\t\tEndpoint: &endpointv3.Endpoint{\n\t\t\t\t\t\t\t\tAddress: &corev3.Address{\n\t\t\t\t\t\t\t\t\tAddress: &corev3.Address_SocketAddress{\n\t\t\t\t\t\t\t\t\t\tSocketAddress: &corev3.SocketAddress{\n\t\t\t\t\t\t\t\t\t\t\tAddress: serviceHost,\n\t\t\t\t\t\t\t\t\t\t\tPortSpecifier: &corev3.SocketAddress_PortValue{\n\t\t\t\t\t\t\t\t\t\t\t\tPortValue: servicePort,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\n// getRouteHostnames determines the effective hostnames for a route.\nfunc getRouteHostnames(routeHostnames []gatewayv1.Hostname, listener gatewayv1.Listener) []string {\n\tif len(routeHostnames) > 0 {\n\t\thostnames := make([]string, len(routeHostnames))\n\t\tfor i, h := range routeHostnames {\n\t\t\thostnames[i] = string(h)\n\t\t}\n\t\treturn hostnames\n\t}\n\tif listener.Hostname != nil && *listener.Hostname != \"\" {\n\t\treturn []string{string(*listener.Hostname)}\n\t}\n\treturn []string{\"*\"}\n}\n\n// setGatewayConditions calculates and sets the final status conditions for the Gateway\n// based on the results of the reconciliation loop.\nfunc setGatewayConditions(newGw *gatewayv1.Gateway, listenerStatuses []gatewayv1.ListenerStatus, err error) {\n\tprogrammedCondition := metav1.Condition{\n\t\tType:               string(gatewayv1.GatewayConditionProgrammed),\n\t\tObservedGeneration: newGw.Generation,\n\t}\n\tif err != nil {\n\t\t// If the Envoy update fails, the Gateway is not programmed.\n\t\tprogrammedCondition.Status = metav1.ConditionFalse\n\t\tprogrammedCondition.Reason = \"ReconciliationError\"\n\t\tprogrammedCondition.Message = fmt.Sprintf(\"Failed to program envoy config: %s\", err.Error())\n\t} else {\n\t\t// If the Envoy update succeeds, check if all individual listeners were programmed.\n\t\tlistenersProgrammed := 0\n\t\tfor _, listenerStatus := range listenerStatuses {\n\t\t\tif meta.IsStatusConditionTrue(listenerStatus.Conditions, string(gatewayv1.ListenerConditionProgrammed)) {\n\t\t\t\tlistenersProgrammed++\n\t\t\t}\n\t\t}\n\n\t\tif listenersProgrammed == len(listenerStatuses) {\n\t\t\t// The Gateway is only fully programmed if all listeners are programmed.\n\t\t\tprogrammedCondition.Status = metav1.ConditionTrue\n\t\t\tprogrammedCondition.Reason = string(gatewayv1.GatewayReasonProgrammed)\n\t\t\tprogrammedCondition.Message = \"Envoy configuration updated successfully\"\n\t\t} else {\n\t\t\t// If any listener failed, the Gateway as a whole is not fully programmed.\n\t\t\tprogrammedCondition.Status = metav1.ConditionFalse\n\t\t\tprogrammedCondition.Reason = \"ListenersNotProgrammed\"\n\t\t\tprogrammedCondition.Message = fmt.Sprintf(\"%d out of %d listeners failed to be programmed\", listenersProgrammed, len(listenerStatuses))\n\t\t}\n\t}\n\tmeta.SetStatusCondition(&newGw.Status.Conditions, programmedCondition)\n\n\tmeta.SetStatusCondition(&newGw.Status.Conditions, metav1.Condition{\n\t\tType:               string(gatewayv1.GatewayConditionAccepted),\n\t\tStatus:             metav1.ConditionTrue,\n\t\tReason:             string(gatewayv1.GatewayReasonAccepted),\n\t\tMessage:            \"Gateway is accepted\",\n\t\tObservedGeneration: newGw.Generation,\n\t})\n}\n"
  },
  {
    "path": "pkg/gateway/gateway_test.go",
    "content": "package gateway\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"k8s.io/utils/ptr\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\nfunc Test_getSupportedKinds(t *testing.T) {\n\ttype args struct {\n\t\tlistener gatewayv1.Listener\n\t}\n\tgroup := gatewayv1.Group(gatewayv1.GroupName)\n\ttests := []struct {\n\t\tname  string\n\t\targs  args\n\t\twant  []gatewayv1.RouteGroupKind\n\t\twant1 bool\n\t}{\n\t\t{\n\t\t\tname: \"default kinds for HTTP protocol\",\n\t\t\targs: args{\n\t\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\t\tProtocol: gatewayv1.HTTPProtocolType,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []gatewayv1.RouteGroupKind{\n\t\t\t\t{Group: &group, Kind: \"HTTPRoute\"},\n\t\t\t},\n\t\t\twant1: true,\n\t\t},\n\t\t{\n\t\t\tname: \"default kinds for HTTPS protocol\",\n\t\t\targs: args{\n\t\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\t\tProtocol: gatewayv1.HTTPSProtocolType,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []gatewayv1.RouteGroupKind{\n\t\t\t\t{Group: &group, Kind: \"HTTPRoute\"},\n\t\t\t},\n\t\t\twant1: true,\n\t\t},\n\t\t{\n\t\t\tname: \"no default kinds for other protocols\",\n\t\t\targs: args{\n\t\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\t\tProtocol: gatewayv1.TCPProtocolType,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant:  []gatewayv1.RouteGroupKind{},\n\t\t\twant1: true,\n\t\t},\n\t\t{\n\t\t\tname: \"user defined kinds\",\n\t\t\targs: args{\n\t\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\t\tProtocol: gatewayv1.HTTPProtocolType,\n\t\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\t\tKinds: []gatewayv1.RouteGroupKind{\n\t\t\t\t\t\t\t{Kind: \"HTTPRoute\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []gatewayv1.RouteGroupKind{\n\t\t\t\t{Group: &group, Kind: \"HTTPRoute\"},\n\t\t\t},\n\t\t\twant1: true,\n\t\t},\n\t\t{\n\t\t\tname: \"user defined kinds with invalid kind\",\n\t\t\targs: args{\n\t\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\t\tProtocol: gatewayv1.HTTPProtocolType,\n\t\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\t\tKinds: []gatewayv1.RouteGroupKind{\n\t\t\t\t\t\t\t{Kind: \"HTTPRoute\"},\n\t\t\t\t\t\t\t{Kind: \"TCPRoute\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []gatewayv1.RouteGroupKind{\n\t\t\t\t{Group: &group, Kind: \"HTTPRoute\"},\n\t\t\t},\n\t\t\twant1: false,\n\t\t},\n\t\t{\n\t\t\tname: \"user defined kinds with invalid group\",\n\t\t\targs: args{\n\t\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\t\tProtocol: gatewayv1.HTTPProtocolType,\n\t\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\t\tKinds: []gatewayv1.RouteGroupKind{\n\t\t\t\t\t\t\t{Group: ptr.To(gatewayv1.Group(\"foo\")), Kind: \"HTTPRoute\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant:  []gatewayv1.RouteGroupKind{},\n\t\t\twant1: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, got1 := getSupportedKinds(tt.args.listener)\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"getSupportedKinds() got = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t\tif got1 != tt.want1 {\n\t\t\t\tt.Errorf(\"getSupportedKinds() got1 = %v, want %v\", got1, tt.want1)\n\t\t\t}\n\t\t})\n\t}\n}"
  },
  {
    "path": "pkg/gateway/grpcroute.go",
    "content": "package gateway\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\troutev3 \"github.com/envoyproxy/go-control-plane/envoy/config/route/v3\"\n\tmatcherv3 \"github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3\"\n\t\"google.golang.org/protobuf/types/known/wrapperspb\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tcorev1listers \"k8s.io/client-go/listers/core/v1\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n// translateGRPCRouteToEnvoyRoutes translates a full GRPCRoute into a slice of Envoy Routes.\n// It is a pure function that returns the result, a list of required cluster names, and a final\n// status condition without mutating any arguments.\nfunc translateGRPCRouteToEnvoyRoutes(\n\tgrpcRoute *gatewayv1.GRPCRoute,\n\tserviceLister corev1listers.ServiceLister,\n) ([]*routev3.Route, []gatewayv1.BackendRef, metav1.Condition) {\n\n\tvar envoyRoutes []*routev3.Route\n\tvar validBackendRefs []gatewayv1.BackendRef\n\tisOverallSuccess := true\n\tvar finalFailureMessage string\n\tvar finalFailureReason gatewayv1.RouteConditionReason\n\n\tfor ruleIndex, rule := range grpcRoute.Spec.Rules {\n\t\t// Attempt to build the forwarding action. This will return an error if backends are invalid.\n\t\trouteAction, backendRefs, err := buildGRPCRouteAction(\n\t\t\tgrpcRoute.Namespace,\n\t\t\trule.BackendRefs,\n\t\t\tserviceLister,\n\t\t)\n\n\t\tvalidBackendRefs = append(validBackendRefs, backendRefs...)\n\n\t\t// This helper function creates the appropriate Envoy route (forward or direct response)\n\t\t// based on the success of the backend resolution.\n\t\tbuildRoutesForRule := func(match gatewayv1.GRPCRouteMatch, matchIndex int) (*routev3.Route, metav1.Condition) {\n\t\t\trouteMatch, matchCondition := translateGRPCRouteMatch(match, grpcRoute.Generation)\n\t\t\tif matchCondition.Status == metav1.ConditionFalse {\n\t\t\t\treturn nil, matchCondition\n\t\t\t}\n\n\t\t\tenvoyRoute := &routev3.Route{\n\t\t\t\tName:  fmt.Sprintf(\"%s-%s-rule%d-match%d\", grpcRoute.Namespace, grpcRoute.Name, ruleIndex, matchIndex),\n\t\t\t\tMatch: routeMatch,\n\t\t\t}\n\t\t\tvar controllerErr *ControllerError\n\t\t\tif errors.As(err, &controllerErr) {\n\t\t\t\t// Backend resolution failed. Create a DirectResponse and a False condition.\n\t\t\t\tif isOverallSuccess { // Capture first failure details\n\t\t\t\t\tisOverallSuccess = false\n\t\t\t\t\tfinalFailureMessage = controllerErr.Message\n\t\t\t\t\tfinalFailureReason = gatewayv1.RouteConditionReason(controllerErr.Reason)\n\t\t\t\t}\n\t\t\t\tenvoyRoute.Action = &routev3.Route_DirectResponse{\n\t\t\t\t\tDirectResponse: &routev3.DirectResponseAction{Status: 500},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Backend resolution succeeded. Create a normal forwarding route.\n\t\t\t\tenvoyRoute.Action = &routev3.Route_Route{\n\t\t\t\t\tRoute: routeAction,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn envoyRoute, createSuccessCondition(grpcRoute.Generation)\n\t\t}\n\n\t\t// GRPCRoute requires at least one match per rule.\n\t\tif len(rule.Matches) == 0 {\n\t\t\tif isOverallSuccess {\n\t\t\t\tisOverallSuccess = false\n\t\t\t\tfinalFailureMessage = \"GRPCRoute rule must have at least one match\"\n\t\t\t\tfinalFailureReason = gatewayv1.RouteReasonBackendNotFound\n\t\t\t}\n\t\t} else {\n\t\t\tfor matchIndex, match := range rule.Matches {\n\t\t\t\tenvoyRoute, cond := buildRoutesForRule(match, matchIndex)\n\t\t\t\tif cond.Status == metav1.ConditionFalse {\n\t\t\t\t\treturn nil, nil, cond\n\t\t\t\t}\n\t\t\t\tenvoyRoutes = append(envoyRoutes, envoyRoute)\n\t\t\t}\n\t\t}\n\t}\n\n\tif isOverallSuccess {\n\t\treturn envoyRoutes, validBackendRefs, createSuccessCondition(grpcRoute.Generation)\n\t}\n\n\treturn envoyRoutes, validBackendRefs, createFailureCondition(finalFailureReason, finalFailureMessage, grpcRoute.Generation)\n}\n\n// buildGRPCRouteAction attempts to create a forwarding RouteAction and returns a structured error on failure.\nfunc buildGRPCRouteAction(\n\tnamespace string,\n\tbackendRefs []gatewayv1.GRPCBackendRef,\n\tserviceLister corev1listers.ServiceLister,\n) (*routev3.RouteAction, []gatewayv1.BackendRef, error) {\n\tweightedClusters := &routev3.WeightedCluster{}\n\tvar validBackendRefs []gatewayv1.BackendRef\n\n\tfor _, backendRef := range backendRefs {\n\t\tns := namespace\n\t\tif backendRef.Namespace != nil {\n\t\t\tns = string(*backendRef.Namespace)\n\t\t}\n\t\tif _, err := serviceLister.Services(ns).Get(string(backendRef.Name)); err != nil {\n\t\t\treturn nil, nil, &ControllerError{\n\t\t\t\tReason:  string(gatewayv1.RouteReasonBackendNotFound),\n\t\t\t\tMessage: \"backend not found\",\n\t\t\t}\n\t\t}\n\t\t// GRPCRoute uses BackendObjectReference which is slightly different but can be converted.\n\t\tclusterName, err := backendRefToClusterName(namespace, backendRef.BackendRef)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tweight := int32(1)\n\t\tif backendRef.Weight != nil {\n\t\t\tweight = *backendRef.Weight\n\t\t}\n\t\tif weight == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tvalidBackendRefs = append(validBackendRefs, backendRef.BackendRef)\n\t\tweightedClusters.Clusters = append(weightedClusters.Clusters, &routev3.WeightedCluster_ClusterWeight{\n\t\t\tName:   clusterName,\n\t\t\tWeight: &wrapperspb.UInt32Value{Value: uint32(weight)},\n\t\t})\n\t}\n\n\tif len(weightedClusters.Clusters) == 0 {\n\t\treturn nil, nil, &ControllerError{Reason: string(gatewayv1.RouteReasonAccepted), Message: \"no valid backends provided with a weight > 0\"}\n\t}\n\n\tvar action *routev3.RouteAction\n\tif len(weightedClusters.Clusters) == 1 {\n\t\taction = &routev3.RouteAction{ClusterSpecifier: &routev3.RouteAction_Cluster{Cluster: weightedClusters.Clusters[0].Name}}\n\t} else {\n\t\taction = &routev3.RouteAction{ClusterSpecifier: &routev3.RouteAction_WeightedClusters{WeightedClusters: weightedClusters}}\n\t}\n\n\treturn action, validBackendRefs, nil\n}\n\n// translateGRPCRouteMatch translates a Gateway API GRPCRouteMatch into an Envoy RouteMatch.\nfunc translateGRPCRouteMatch(match gatewayv1.GRPCRouteMatch, generation int64) (*routev3.RouteMatch, metav1.Condition) {\n\trouteMatch := &routev3.RouteMatch{\n\t\t// gRPC requests are HTTP/2 POSTs with a specific content-type.\n\t\tHeaders: []*routev3.HeaderMatcher{\n\t\t\t{\n\t\t\t\tName:                 \":method\",\n\t\t\t\tHeaderMatchSpecifier: &routev3.HeaderMatcher_ExactMatch{ExactMatch: \"POST\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:                 \"content-type\",\n\t\t\t\tHeaderMatchSpecifier: &routev3.HeaderMatcher_PrefixMatch{PrefixMatch: \"application/grpc\"},\n\t\t\t},\n\t\t},\n\t}\n\n\t// Translate gRPC method match into a :path header match.\n\tif match.Method != nil {\n\t\tif match.Method.Service == nil || match.Method.Method == nil {\n\t\t\tmsg := \"GRPCMethodMatch requires both service and method to be set\"\n\t\t\treturn nil, createFailureCondition(gatewayv1.RouteReasonUnsupportedValue, msg, generation)\n\t\t}\n\t\tpath := fmt.Sprintf(\"/%s/%s\", *match.Method.Service, *match.Method.Method)\n\t\tmatchType := gatewayv1.GRPCMethodMatchExact\n\t\tif match.Method.Type != nil {\n\t\t\tmatchType = *match.Method.Type\n\t\t}\n\n\t\tpathMatcher := &routev3.HeaderMatcher{Name: \":path\"}\n\t\tswitch matchType {\n\t\tcase gatewayv1.GRPCMethodMatchExact:\n\t\t\tpathMatcher.HeaderMatchSpecifier = &routev3.HeaderMatcher_ExactMatch{ExactMatch: path}\n\t\tcase gatewayv1.GRPCMethodMatchRegularExpression:\n\t\t\tpathMatcher.HeaderMatchSpecifier = &routev3.HeaderMatcher_SafeRegexMatch{\n\t\t\t\tSafeRegexMatch: &matcherv3.RegexMatcher{\n\t\t\t\t\tEngineType: &matcherv3.RegexMatcher_GoogleRe2{GoogleRe2: &matcherv3.RegexMatcher_GoogleRE2{}},\n\t\t\t\t\tRegex:      path,\n\t\t\t\t},\n\t\t\t}\n\t\tdefault:\n\t\t\tmsg := fmt.Sprintf(\"unsupported gRPC method match type: %s\", matchType)\n\t\t\treturn nil, createFailureCondition(gatewayv1.RouteReasonUnsupportedValue, msg, generation)\n\t\t}\n\t\trouteMatch.Headers = append(routeMatch.Headers, pathMatcher)\n\t}\n\n\t// Translate header matches.\n\tfor _, headerMatch := range match.Headers {\n\t\theaderMatcher := &routev3.HeaderMatcher{Name: string(headerMatch.Name)}\n\t\tmatchType := gatewayv1.GRPCHeaderMatchExact\n\t\tif headerMatch.Type != nil {\n\t\t\tmatchType = *headerMatch.Type\n\t\t}\n\n\t\tswitch matchType {\n\t\tcase gatewayv1.GRPCHeaderMatchExact:\n\t\t\t// CHANGED: Use the modern direct `ExactMatch` field.\n\t\t\theaderMatcher.HeaderMatchSpecifier = &routev3.HeaderMatcher_ExactMatch{ExactMatch: headerMatch.Value}\n\t\tcase gatewayv1.GRPCHeaderMatchRegularExpression:\n\t\t\theaderMatcher.HeaderMatchSpecifier = &routev3.HeaderMatcher_SafeRegexMatch{\n\t\t\t\tSafeRegexMatch: &matcherv3.RegexMatcher{\n\t\t\t\t\tEngineType: &matcherv3.RegexMatcher_GoogleRe2{GoogleRe2: &matcherv3.RegexMatcher_GoogleRE2{}},\n\t\t\t\t\tRegex:      headerMatch.Value,\n\t\t\t\t},\n\t\t\t}\n\t\tdefault:\n\t\t\tmsg := fmt.Sprintf(\"unsupported header match type: %s\", matchType)\n\t\t\treturn nil, createFailureCondition(gatewayv1.RouteReasonUnsupportedValue, msg, generation)\n\t\t}\n\t\trouteMatch.Headers = append(routeMatch.Headers, headerMatcher)\n\t}\n\n\treturn routeMatch, createSuccessCondition(generation)\n}\n"
  },
  {
    "path": "pkg/gateway/httproute.go",
    "content": "package gateway\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\tcorev3 \"github.com/envoyproxy/go-control-plane/envoy/config/core/v3\"\n\troutev3 \"github.com/envoyproxy/go-control-plane/envoy/config/route/v3\"\n\tmatcherv3 \"github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3\"\n\t\"google.golang.org/protobuf/types/known/wrapperspb\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\n\tcorev1listers \"k8s.io/client-go/listers/core/v1\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n\tgatewaylistersv1 \"sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1\"\n)\n\n// translateHTTPRouteToEnvoyRoutes translates a full HTTPRoute into a slice of Envoy Routes.\n// It now correctly handles RequestHeaderModifier filters.\nfunc translateHTTPRouteToEnvoyRoutes(\n\thttpRoute *gatewayv1.HTTPRoute,\n\tserviceLister corev1listers.ServiceLister,\n\treferenceGrantLister gatewaylistersv1.ReferenceGrantLister,\n) ([]*routev3.Route, []gatewayv1.BackendRef, metav1.Condition) {\n\n\tvar envoyRoutes []*routev3.Route\n\tvar allValidBackendRefs []gatewayv1.BackendRef\n\toverallCondition := createSuccessCondition(httpRoute.Generation)\n\n\tfor ruleIndex, rule := range httpRoute.Spec.Rules {\n\t\tvar redirectAction *routev3.RedirectAction\n\t\tvar headersToAdd []*corev3.HeaderValueOption\n\t\tvar headersToRemove []string\n\t\tfor _, filter := range rule.Filters {\n\t\t\tif filter.Type == gatewayv1.HTTPRouteFilterRequestRedirect && filter.RequestRedirect != nil {\n\t\t\t\tredirect := filter.RequestRedirect\n\t\t\t\tredirectAction = &routev3.RedirectAction{}\n\n\t\t\t\tif redirect.Hostname != nil {\n\t\t\t\t\tredirectAction.HostRedirect = string(*redirect.Hostname)\n\t\t\t\t}\n\n\t\t\t\tif redirect.StatusCode != nil {\n\t\t\t\t\tswitch *redirect.StatusCode {\n\t\t\t\t\tcase 301:\n\t\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_MOVED_PERMANENTLY\n\t\t\t\t\tcase 302:\n\t\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_FOUND\n\t\t\t\t\tcase 303:\n\t\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_SEE_OTHER\n\t\t\t\t\tcase 307:\n\t\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_TEMPORARY_REDIRECT\n\t\t\t\t\tcase 308:\n\t\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_PERMANENT_REDIRECT\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_MOVED_PERMANENTLY\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// The Gateway API spec defaults to a 302 redirect.\n\t\t\t\t\t// The corresponding Envoy enum is \"FOUND\".\n\t\t\t\t\tredirectAction.ResponseCode = routev3.RedirectAction_FOUND\n\t\t\t\t}\n\n\t\t\t\tbreak // Only one redirect filter is allowed per rule.\n\t\t\t}\n\n\t\t\tif filter.Type == gatewayv1.HTTPRouteFilterRequestHeaderModifier && filter.RequestHeaderModifier != nil {\n\t\t\t\t// Handle \"set\" actions (overwrite)\n\t\t\t\tfor _, header := range filter.RequestHeaderModifier.Set {\n\t\t\t\t\theadersToAdd = append(headersToAdd, &corev3.HeaderValueOption{\n\t\t\t\t\t\tHeader: &corev3.HeaderValue{\n\t\t\t\t\t\t\tKey:   string(header.Name),\n\t\t\t\t\t\t\tValue: header.Value,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// This tells Envoy to overwrite the header if it exists.\n\t\t\t\t\t\tAppendAction: corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\t// Handle \"add\" actions (append)\n\t\t\t\tfor _, header := range filter.RequestHeaderModifier.Add {\n\t\t\t\t\theadersToAdd = append(headersToAdd, &corev3.HeaderValueOption{\n\t\t\t\t\t\tHeader: &corev3.HeaderValue{\n\t\t\t\t\t\t\tKey:   string(header.Name),\n\t\t\t\t\t\t\tValue: header.Value,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// This tells Envoy to append the value if the header already exists.\n\t\t\t\t\t\tAppendAction: corev3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\t// Handle \"remove\" actions\n\t\t\t\theadersToRemove = append(headersToRemove, filter.RequestHeaderModifier.Remove...)\n\t\t\t}\n\t\t}\n\n\t\tbuildRoutesForRule := func(match gatewayv1.HTTPRouteMatch, matchIndex int) {\n\t\t\trouteMatch, matchCondition := translateHTTPRouteMatch(match, httpRoute.Generation)\n\t\t\tif matchCondition.Status == metav1.ConditionFalse {\n\t\t\t\toverallCondition = matchCondition\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tenvoyRoute := &routev3.Route{\n\t\t\t\tName:                   fmt.Sprintf(\"%s-%s-rule%d-match%d\", httpRoute.Namespace, httpRoute.Name, ruleIndex, matchIndex),\n\t\t\t\tMatch:                  routeMatch,\n\t\t\t\tRequestHeadersToAdd:    headersToAdd,\n\t\t\t\tRequestHeadersToRemove: headersToRemove,\n\t\t\t}\n\n\t\t\tif redirectAction != nil {\n\t\t\t\t// If this is a redirect, set the Redirect action. No backends are needed.\n\t\t\t\tenvoyRoute.Action = &routev3.Route_Redirect{\n\t\t\t\t\tRedirect: redirectAction,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Attempt to build the forwarding action and get valid backends.\n\t\t\t\trouteAction, validBackends, err := buildHTTPRouteAction(\n\t\t\t\t\thttpRoute.Namespace,\n\t\t\t\t\trule.BackendRefs,\n\t\t\t\t\tserviceLister,\n\t\t\t\t\treferenceGrantLister,\n\t\t\t\t)\n\t\t\t\tvar controllerErr *ControllerError\n\t\t\t\tif errors.As(err, &controllerErr) {\n\t\t\t\t\toverallCondition = createFailureCondition(gatewayv1.RouteConditionReason(controllerErr.Reason), controllerErr.Message, httpRoute.Generation)\n\t\t\t\t\tenvoyRoute.Action = &routev3.Route_DirectResponse{\n\t\t\t\t\t\tDirectResponse: &routev3.DirectResponseAction{Status: 500},\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tallValidBackendRefs = append(allValidBackendRefs, validBackends...)\n\t\t\t\t\tenvoyRoute.Action = &routev3.Route_Route{\n\t\t\t\t\t\tRoute: routeAction,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tenvoyRoutes = append(envoyRoutes, envoyRoute)\n\t\t}\n\n\t\tif len(rule.Matches) == 0 {\n\t\t\tbuildRoutesForRule(gatewayv1.HTTPRouteMatch{}, 0)\n\t\t} else {\n\t\t\tfor matchIndex, match := range rule.Matches {\n\t\t\t\tbuildRoutesForRule(match, matchIndex)\n\t\t\t}\n\t\t}\n\t}\n\treturn envoyRoutes, allValidBackendRefs, overallCondition\n}\n\n// buildHTTPRouteAction returns an action, a list of *valid* BackendRefs, and a structured error.\nfunc buildHTTPRouteAction(namespace string, backendRefs []gatewayv1.HTTPBackendRef, serviceLister corev1listers.ServiceLister, referenceGrantLister gatewaylistersv1.ReferenceGrantLister) (*routev3.RouteAction, []gatewayv1.BackendRef, error) {\n\tweightedClusters := &routev3.WeightedCluster{}\n\tvar validBackendRefs []gatewayv1.BackendRef\n\n\tfor _, httpBackendRef := range backendRefs {\n\t\tbackendRef := httpBackendRef.BackendRef\n\n\t\tns := namespace\n\t\tif backendRef.Namespace != nil {\n\t\t\tns = string(*backendRef.Namespace)\n\t\t}\n\n\t\t// If it's a cross-namespace reference, we must check for a ReferenceGrant.\n\t\tif ns != namespace {\n\t\t\tfrom := gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayv1.GroupName,\n\t\t\t\tKind:      \"HTTPRoute\",\n\t\t\t\tNamespace: gatewayv1.Namespace(namespace),\n\t\t\t}\n\t\t\tto := gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: \"\", // Core group for Service\n\t\t\t\tKind:  \"Service\",\n\t\t\t\tName:  &backendRef.Name,\n\t\t\t}\n\n\t\t\tif !isCrossNamespaceRefAllowed(from, to, ns, referenceGrantLister) {\n\t\t\t\t// The reference is not permitted.\n\t\t\t\treturn nil, nil, &ControllerError{\n\t\t\t\t\tReason:  string(gatewayv1.RouteReasonRefNotPermitted),\n\t\t\t\t\tMessage: \"permission error\",\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif _, err := serviceLister.Services(ns).Get(string(backendRef.Name)); err != nil {\n\t\t\treturn nil, nil, &ControllerError{\n\t\t\t\tReason:  string(gatewayv1.RouteReasonBackendNotFound),\n\t\t\t\tMessage: \"backend not found\",\n\t\t\t}\n\t\t}\n\t\tclusterName, err := backendRefToClusterName(namespace, backendRef)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tweight := int32(1)\n\t\tif httpBackendRef.Weight != nil {\n\t\t\tweight = *httpBackendRef.Weight\n\t\t}\n\t\tif weight == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tvalidBackendRefs = append(validBackendRefs, backendRef)\n\t\tweightedClusters.Clusters = append(weightedClusters.Clusters, &routev3.WeightedCluster_ClusterWeight{\n\t\t\tName:   clusterName,\n\t\t\tWeight: &wrapperspb.UInt32Value{Value: uint32(weight)},\n\t\t})\n\t}\n\n\tif len(weightedClusters.Clusters) == 0 {\n\t\treturn nil, nil, &ControllerError{Reason: string(gatewayv1.RouteReasonUnsupportedValue), Message: \"no valid backends provided with a weight > 0\"}\n\t}\n\n\tvar action *routev3.RouteAction\n\tif len(weightedClusters.Clusters) == 1 {\n\t\taction = &routev3.RouteAction{ClusterSpecifier: &routev3.RouteAction_Cluster{Cluster: weightedClusters.Clusters[0].Name}}\n\t} else {\n\t\taction = &routev3.RouteAction{ClusterSpecifier: &routev3.RouteAction_WeightedClusters{WeightedClusters: weightedClusters}}\n\t}\n\n\treturn action, validBackendRefs, nil\n}\n\n// translateHTTPRouteMatch translates a Gateway API HTTPRouteMatch into an Envoy RouteMatch.\n// It returns the result and a condition indicating success or failure.\nfunc translateHTTPRouteMatch(match gatewayv1.HTTPRouteMatch, generation int64) (*routev3.RouteMatch, metav1.Condition) {\n\trouteMatch := &routev3.RouteMatch{}\n\n\tif match.Path != nil {\n\t\tpathType := gatewayv1.PathMatchPathPrefix\n\t\tif match.Path.Type != nil {\n\t\t\tpathType = *match.Path.Type\n\t\t}\n\t\tif match.Path.Value == nil {\n\t\t\tmsg := \"path match value cannot be nil\"\n\t\t\treturn nil, createFailureCondition(gatewayv1.RouteReasonUnsupportedValue, msg, generation)\n\t\t}\n\t\tpathValue := *match.Path.Value\n\n\t\tswitch pathType {\n\t\tcase gatewayv1.PathMatchExact:\n\t\t\trouteMatch.PathSpecifier = &routev3.RouteMatch_Path{Path: pathValue}\n\t\tcase gatewayv1.PathMatchPathPrefix:\n\t\t\tif pathValue == \"/\" {\n\t\t\t\trouteMatch.PathSpecifier = &routev3.RouteMatch_Prefix{Prefix: \"/\"}\n\t\t\t} else {\n\t\t\t\tpath := strings.TrimSuffix(pathValue, \"/\")\n\t\t\t\trouteMatch.PathSpecifier = &routev3.RouteMatch_PathSeparatedPrefix{PathSeparatedPrefix: path}\n\t\t\t}\n\t\tcase gatewayv1.PathMatchRegularExpression:\n\t\t\trouteMatch.PathSpecifier = &routev3.RouteMatch_SafeRegex{\n\t\t\t\tSafeRegex: &matcherv3.RegexMatcher{\n\t\t\t\t\tEngineType: &matcherv3.RegexMatcher_GoogleRe2{GoogleRe2: &matcherv3.RegexMatcher_GoogleRE2{}},\n\t\t\t\t\tRegex:      pathValue,\n\t\t\t\t},\n\t\t\t}\n\t\tdefault:\n\t\t\tmsg := fmt.Sprintf(\"unsupported path match type: %s\", pathType)\n\t\t\treturn nil, createFailureCondition(gatewayv1.RouteReasonUnsupportedValue, msg, generation)\n\t\t}\n\t} else {\n\t\t// As per Gateway API spec, a nil path match defaults to matching everything.\n\t\trouteMatch.PathSpecifier = &routev3.RouteMatch_Prefix{Prefix: \"/\"}\n\t}\n\n\t// Translate Header Matches\n\tfor _, headerMatch := range match.Headers {\n\t\theaderMatcher := &routev3.HeaderMatcher{\n\t\t\tName: string(headerMatch.Name),\n\t\t}\n\t\tmatchType := gatewayv1.HeaderMatchExact\n\t\tif headerMatch.Type != nil {\n\t\t\tmatchType = *headerMatch.Type\n\t\t}\n\n\t\tswitch matchType {\n\t\tcase gatewayv1.HeaderMatchExact:\n\t\t\theaderMatcher.HeaderMatchSpecifier = &routev3.HeaderMatcher_StringMatch{\n\t\t\t\tStringMatch: &matcherv3.StringMatcher{\n\t\t\t\t\tMatchPattern: &matcherv3.StringMatcher_Exact{Exact: headerMatch.Value},\n\t\t\t\t},\n\t\t\t}\n\t\tcase gatewayv1.HeaderMatchRegularExpression:\n\t\t\theaderMatcher.HeaderMatchSpecifier = &routev3.HeaderMatcher_SafeRegexMatch{\n\t\t\t\tSafeRegexMatch: &matcherv3.RegexMatcher{\n\t\t\t\t\tEngineType: &matcherv3.RegexMatcher_GoogleRe2{GoogleRe2: &matcherv3.RegexMatcher_GoogleRE2{}},\n\t\t\t\t\tRegex:      headerMatch.Value,\n\t\t\t\t},\n\t\t\t}\n\t\tdefault:\n\t\t\tmsg := fmt.Sprintf(\"unsupported header match type: %s\", matchType)\n\t\t\treturn nil, createFailureCondition(gatewayv1.RouteReasonUnsupportedValue, msg, generation)\n\t\t}\n\t\trouteMatch.Headers = append(routeMatch.Headers, headerMatcher)\n\t}\n\n\t// Translate Query Parameter Matches\n\tfor _, queryMatch := range match.QueryParams {\n\t\t// Gateway API only supports \"Exact\" match for query parameters.\n\t\tqueryMatcher := &routev3.QueryParameterMatcher{\n\t\t\tName: string(queryMatch.Name),\n\t\t\tQueryParameterMatchSpecifier: &routev3.QueryParameterMatcher_StringMatch{\n\t\t\t\tStringMatch: &matcherv3.StringMatcher{\n\t\t\t\t\tMatchPattern: &matcherv3.StringMatcher_Exact{Exact: queryMatch.Value},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\trouteMatch.QueryParameters = append(routeMatch.QueryParameters, queryMatcher)\n\t}\n\n\t// If all translations were successful, return the final object and a success condition.\n\treturn routeMatch, createSuccessCondition(generation)\n}\n\nfunc createSuccessCondition(generation int64) metav1.Condition {\n\treturn metav1.Condition{\n\t\tType:               string(gatewayv1.RouteConditionResolvedRefs),\n\t\tStatus:             metav1.ConditionTrue,\n\t\tReason:             string(gatewayv1.RouteReasonResolvedRefs),\n\t\tMessage:            \"All references resolved\",\n\t\tObservedGeneration: generation,\n\t}\n}\n\nfunc createFailureCondition(reason gatewayv1.RouteConditionReason, message string, generation int64) metav1.Condition {\n\treturn metav1.Condition{\n\t\tType:               string(gatewayv1.RouteConditionResolvedRefs),\n\t\tStatus:             metav1.ConditionFalse,\n\t\tReason:             string(reason),\n\t\tMessage:            message,\n\t\tObservedGeneration: generation,\n\t}\n}\n\n// sortRoutes is the definitive sorter for Envoy routes based on Gateway API precedence.\nfunc sortRoutes(routes []*routev3.Route) {\n\tsort.Slice(routes, func(i, j int) bool {\n\t\tmatchI := routes[i].GetMatch()\n\t\tmatchJ := routes[j].GetMatch()\n\n\t\t// De-prioritize the catch-all route, ensuring it's always last.\n\t\tisCatchAllI := isCatchAll(matchI)\n\t\tisCatchAllJ := isCatchAll(matchJ)\n\n\t\tif isCatchAllI != isCatchAllJ {\n\t\t\t// If I is the catch-all, it should come after J (return false).\n\t\t\t// If J is the catch-all, it should come after I (return true).\n\t\t\treturn isCatchAllJ\n\t\t}\n\n\t\t// Precedence Rule 1: Exact Path Match vs. Other Path Matches\n\t\tisExactPathI := matchI.GetPath() != \"\"\n\t\tisExactPathJ := matchJ.GetPath() != \"\"\n\t\tif isExactPathI != isExactPathJ {\n\t\t\treturn isExactPathI // Exact path is higher precedence\n\t\t}\n\n\t\t// Precedence Rule 2: Longest Prefix Match\n\t\tprefixI := getPathMatchValue(matchI)\n\t\tprefixJ := getPathMatchValue(matchJ)\n\n\t\tif len(prefixI) != len(prefixJ) {\n\t\t\treturn len(prefixI) > len(prefixJ) // Longer prefix is higher precedence\n\t\t}\n\n\t\t// Precedence Rule 3: Number of Header Matches\n\t\theaderCountI := len(matchI.GetHeaders())\n\t\theaderCountJ := len(matchJ.GetHeaders())\n\t\tif headerCountI != headerCountJ {\n\t\t\treturn headerCountI > headerCountJ // More headers is higher precedence\n\t\t}\n\n\t\t// Precedence Rule 4: Number of Query Param Matches\n\t\tqueryCountI := len(matchI.GetQueryParameters())\n\t\tqueryCountJ := len(matchJ.GetQueryParameters())\n\t\tif queryCountI != queryCountJ {\n\t\t\treturn queryCountI > queryCountJ // More query params is higher precedence\n\t\t}\n\n\t\t// If all else is equal, maintain original order (stable sort)\n\t\treturn false\n\t})\n}\n\n// getPathMatchValue is a helper to extract the path string for comparison.\nfunc getPathMatchValue(match *routev3.RouteMatch) string {\n\tif match.GetPath() != \"\" {\n\t\treturn match.GetPath()\n\t}\n\tif match.GetPrefix() != \"\" {\n\t\treturn match.GetPrefix()\n\t}\n\tif match.GetPathSeparatedPrefix() != \"\" {\n\t\treturn match.GetPathSeparatedPrefix()\n\t}\n\tif sr := match.GetSafeRegex(); sr != nil { // Regex Match (used for other PathPrefix)\n\t\t// This correctly handles the output of translateHTTPRouteMatch.\n\t\tregex := sr.GetRegex()\n\t\t// Remove the trailing regex that matches subpaths.\n\t\tpath := strings.TrimSuffix(regex, \"(/.*)?\")\n\t\t// Remove the quoting added by regexp.QuoteMeta.\n\t\tpath = strings.ReplaceAll(path, `\\`, \"\")\n\t\treturn path\n\t}\n\treturn \"\"\n}\n\n// isCatchAll determines if a route match is a generic \"catch-all\" rule.\n// A catch-all matches all paths (\"/\") and has no other specific conditions.\nfunc isCatchAll(match *routev3.RouteMatch) bool {\n\tif match == nil {\n\t\treturn false\n\t}\n\t// It's a catch-all if the path match is for \"/\" AND there are no other constraints.\n\tisRootPrefix := match.GetPrefix() == \"/\"\n\thasNoHeaders := len(match.GetHeaders()) == 0\n\thasNoParams := len(match.GetQueryParameters()) == 0\n\n\treturn isRootPrefix && hasNoHeaders && hasNoParams\n}\n"
  },
  {
    "path": "pkg/gateway/kindcluster.go",
    "content": "package gateway\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"net/netip\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/klog/v2\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n//go:embed routeadder/route-adder-amd64\nvar routeAdderAmd64 []byte\n\n//go:embed routeadder/route-adder-arm64\nvar routeAdderArm64 []byte\n\nfunc getRouteAdderBinaryForArch() ([]byte, error) {\n\tarch := runtime.GOARCH\n\n\tswitch arch {\n\tcase \"amd64\":\n\t\treturn routeAdderAmd64, nil\n\tcase \"arm64\":\n\t\treturn routeAdderArm64, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported architecture: %s\", arch)\n\t}\n}\n\n// getClusterRoutingMap creates a unified map of all routes required for the container.\n// It includes routes for each node's PodCIDRs and for the cluster's ServiceCIDRs.\nfunc (c *Controller) getClusterRoutingMap(ctx context.Context) (map[string]string, error) {\n\tnodes, err := c.client.CoreV1().Nodes().List(ctx, metav1.ListOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list kubernetes nodes: %w\", err)\n\t}\n\tif len(nodes.Items) == 0 {\n\t\treturn nil, fmt.Errorf(\"no kubernetes nodes found in the cluster\")\n\t}\n\n\trouteMap := make(map[string]string)\n\tcontrolPlaneIPs := make(map[bool]string) // map[isIPv6]address\n\n\t// --- 1. Process all nodes for PodCIDR routes and find a control-plane IP ---\n\tfor _, node := range nodes.Items {\n\t\tnodeIPs := make(map[bool]string) // map[isIPv6]address\n\t\tfor _, addr := range node.Status.Addresses {\n\t\t\tif addr.Type == corev1.NodeInternalIP {\n\t\t\t\tip, err := netip.ParseAddr(addr.Address)\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue // Skip invalid IPs\n\t\t\t\t}\n\t\t\t\tnodeIPs[ip.Is6()] = addr.Address\n\t\t\t}\n\t\t}\n\n\t\t// If this is a control-plane node, save its IPs for service routes\n\t\tif _, ok := node.Labels[\"node-role.kubernetes.io/control-plane\"]; ok && len(controlPlaneIPs) == 0 {\n\t\t\tcontrolPlaneIPs = nodeIPs\n\t\t}\n\n\t\t// Map PodCIDRs to this node's IPs, matching family\n\t\tfor _, podCIDR := range node.Spec.PodCIDRs {\n\t\t\tprefix, err := netip.ParsePrefix(podCIDR)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif gatewayIP, found := nodeIPs[prefix.Addr().Is6()]; found {\n\t\t\t\trouteMap[podCIDR] = gatewayIP\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(controlPlaneIPs) == 0 {\n\t\treturn nil, fmt.Errorf(\"could not find any control-plane node to use as a gateway for services\")\n\t}\n\n\t// --- 2. Get ServiceCIDRs and add them to the map ---\n\tserviceCIDRs, err := c.getServiceCIDRs(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get service CIDRs: %w\", err)\n\t}\n\n\tfor _, serviceCIDR := range serviceCIDRs {\n\t\tprefix, err := netip.ParsePrefix(serviceCIDR)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Invalid ServiceCIDR '%s', skipping.\", serviceCIDR)\n\t\t\tcontinue\n\t\t}\n\t\t// Match the service CIDR family to the control-plane IP family\n\t\tif gatewayIP, found := controlPlaneIPs[prefix.Addr().Is6()]; found {\n\t\t\tklog.Infof(\"Found route for services: ServiceCIDR %s -> Gateway %s\", serviceCIDR, gatewayIP)\n\t\t\trouteMap[serviceCIDR] = gatewayIP\n\t\t} else {\n\t\t\tklog.Warningf(\"No matching control-plane IP found for ServiceCIDR family '%s'\", serviceCIDR)\n\t\t}\n\t}\n\n\tif len(routeMap) == 0 {\n\t\treturn nil, fmt.Errorf(\"could not construct any valid routes\")\n\t}\n\n\treturn routeMap, nil\n}\n\nfunc (c *Controller) getServiceCIDRs(ctx context.Context) ([]string, error) {\n\tserviceCIDRs, err := c.client.NetworkingV1().ServiceCIDRs().List(ctx, metav1.ListOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list servicecidrs: %w. Is the ServiceCIDR feature gate enabled?\", err)\n\t}\n\tif len(serviceCIDRs.Items) == 0 {\n\t\treturn nil, fmt.Errorf(\"no servicecidrs found in the cluster\")\n\t}\n\n\tcidrs := sets.Set[string]{}\n\tfor _, serviceCIDRObject := range serviceCIDRs.Items {\n\t\tcidrs.Insert(serviceCIDRObject.Spec.CIDRs...)\n\t}\n\tif len(cidrs) == 0 {\n\t\treturn nil, fmt.Errorf(\"no CIDRs found in any ServiceCIDR object\")\n\t}\n\treturn cidrs.UnsortedList(), nil\n}\n\nfunc (c *Controller) configureContainerNetworking(ctx context.Context, containerName string) error {\n\tbinaryData, err := getRouteAdderBinaryForArch()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcontainerBinaryPath := \"/tmp/route-adder\"\n\n\t// 2. Combine copy and chmod into a single Exec call.\n\t// The shell command 'cat > file && chmod +x file' does both steps sequentially.\n\tsetupCmd := []string{\"sh\", \"-c\", fmt.Sprintf(\"cat > %s && chmod +x %s\", containerBinaryPath, containerBinaryPath)}\n\tstdinReader := bytes.NewReader(binaryData)\n\n\tklog.Infof(\"Streaming and setting up route-adder utility in %s\", containerName)\n\tif err := container.Exec(containerName, setupCmd, stdinReader, nil, nil); err != nil {\n\t\treturn fmt.Errorf(\"failed to setup route-adder binary in container %s: %w\", containerName, err)\n\t}\n\tklog.Infof(\"Successfully installed route-adder utility in container %s\", containerName)\n\trouteMap, err := c.getClusterRoutingMap(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get kubernetes cluster routing information: %w\", err)\n\t}\n\n\t// 3. Iterate through the map and add a route for each entry.\n\tvar routesAdded int\n\tvar stdout, stderr bytes.Buffer\n\tfor cidr, gatewayIP := range routeMap {\n\t\tcmd := []string{containerBinaryPath, cidr, gatewayIP}\n\t\tklog.Infof(\"Adding route to container %s: %s\", containerName, strings.Join(cmd, \" \"))\n\n\t\tstdout.Reset()\n\t\tstderr.Reset()\n\t\tif err := container.Exec(containerName, cmd, nil, &stdout, &stderr); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to add route '%s' via %s to container %s: %w, stderr: %s\",\n\t\t\t\tcidr, gatewayIP, containerName, err, stderr.String())\n\t\t}\n\t\troutesAdded++\n\t}\n\n\tif routesAdded == 0 {\n\t\treturn fmt.Errorf(\"no valid cluster routes were found to configure\")\n\t}\n\n\tklog.Infof(\"Successfully added %d pod and service routes to container %s\", routesAdded, containerName)\n\treturn nil\n}\n\nfunc (c *Controller) ensureGatewayContainer(ctx context.Context, gw *gatewayv1.Gateway) error {\n\tnamespace := gw.Namespace\n\tname := gw.Name\n\tcontainerName := gatewayName(c.clusterName, namespace, name)\n\n\tif !container.IsRunning(containerName) {\n\t\tklog.Infof(\"container %s for gateway %s/%s is not running\", containerName, namespace, name)\n\t\tif container.Exist(containerName) {\n\t\t\tif err := container.Delete(containerName); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tif !container.Exist(containerName) {\n\t\tklog.V(2).Infof(\"creating container %s for gateway  %s/%s on cluster %s\", containerName, namespace, name, c.clusterName)\n\t\tenableTunnels := c.tunnelManager != nil || config.DefaultConfig.LoadBalancerConnectivity == config.Portmap\n\t\terr := createGateway(c.clusterName, c.clusterNameserver, c.xdsLocalAddress, c.xdsLocalPort, gw, enableTunnels)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// TODO fix this hack\n\t\ttime.Sleep(250 * time.Millisecond)\n\n\t\tif err := c.configureContainerNetworking(ctx, containerName); err != nil {\n\t\t\tif delErr := container.Delete(containerName); delErr != nil {\n\t\t\t\tklog.Errorf(\"failed to delete container %s after networking setup failed: %v\", containerName, delErr)\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"failed to configure networking for new gateway container %s: %w\", containerName, err)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/gateway/listener.go",
    "content": "package gateway\n\nimport (\n\t\"context\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\n\tcorev3 \"github.com/envoyproxy/go-control-plane/envoy/config/core/v3\"\n\tlistener \"github.com/envoyproxy/go-control-plane/envoy/config/listener/v3\"\n\troutev3 \"github.com/envoyproxy/go-control-plane/envoy/config/route/v3\"\n\trouterv3 \"github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3\"\n\ttlsinspector \"github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/tls_inspector/v3\"\n\thcm \"github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3\"\n\ttcpproxyv3 \"github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3\"\n\tudpproxy \"github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/udp_proxy/v3\"\n\ttlsv3 \"github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3\"\n\t\"github.com/envoyproxy/go-control-plane/pkg/wellknown\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\t\"google.golang.org/protobuf/types/known/wrapperspb\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/klog/v2\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n// setListenerCondition is a helper to safely set a condition on a listener's status\n// in a map of conditions.\nfunc setListenerCondition(\n\tconditionsMap map[gatewayv1.SectionName][]metav1.Condition,\n\tlistenerName gatewayv1.SectionName,\n\tcondition metav1.Condition,\n) {\n\t// This \"get, modify, set\" pattern is the standard way to\n\t// work around the Go constraint that map values are not addressable.\n\tconditions := conditionsMap[listenerName]\n\tif conditions == nil {\n\t\tconditions = []metav1.Condition{}\n\t}\n\tmeta.SetStatusCondition(&conditions, condition)\n\tconditionsMap[listenerName] = conditions\n}\n\n// validateListeners checks for conflicts among all listeners on a Gateway as per the spec.\n// It returns a map of conflicted listener conditions and a Gateway-level condition if any conflicts exist.\nfunc (c *Controller) validateListeners(gateway *gatewayv1.Gateway) map[gatewayv1.SectionName][]metav1.Condition {\n\tlistenerConditions := make(map[gatewayv1.SectionName][]metav1.Condition)\n\tfor _, listener := range gateway.Spec.Listeners {\n\t\t// Initialize with a fresh slice.\n\t\tlistenerConditions[listener.Name] = []metav1.Condition{}\n\t}\n\n\t// Check for Port and Hostname Conflicts\n\tlistenersByPort := make(map[gatewayv1.PortNumber][]gatewayv1.Listener)\n\tfor _, listener := range gateway.Spec.Listeners {\n\t\tlistenersByPort[listener.Port] = append(listenersByPort[listener.Port], listener)\n\t}\n\n\tfor _, listenersOnPort := range listenersByPort {\n\t\t// Rule: A TCP listener cannot share a port with HTTP/HTTPS/TLS listeners.\n\t\thasTCP := false\n\t\thasHTTPTLS := false\n\t\tfor _, listener := range listenersOnPort {\n\t\t\tif listener.Protocol == gatewayv1.TCPProtocolType || listener.Protocol == gatewayv1.UDPProtocolType {\n\t\t\t\thasTCP = true\n\t\t\t}\n\t\t\tif listener.Protocol == gatewayv1.HTTPProtocolType || listener.Protocol == gatewayv1.HTTPSProtocolType || listener.Protocol == gatewayv1.TLSProtocolType {\n\t\t\t\thasHTTPTLS = true\n\t\t\t}\n\t\t}\n\n\t\tif hasTCP && hasHTTPTLS {\n\t\t\tfor _, listener := range listenersOnPort {\n\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\t\tType:    string(gatewayv1.ListenerConditionConflicted),\n\t\t\t\t\tStatus:  metav1.ConditionTrue,\n\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonProtocolConflict),\n\t\t\t\t\tMessage: \"Protocol conflict: TCP/UDP listeners cannot share a port with HTTP/HTTPS/TLS listeners.\",\n\t\t\t\t})\n\t\t\t}\n\t\t\tcontinue // Skip further checks for this port\n\t\t}\n\n\t\t// Rule: HTTP/HTTPS/TLS listeners on the same port must have unique hostnames.\n\t\tseenHostnames := make(map[gatewayv1.Hostname]gatewayv1.SectionName)\n\t\tfor _, listener := range listenersOnPort {\n\t\t\t// This check only applies to protocols that use hostnames for distinction.\n\t\t\tif listener.Protocol == gatewayv1.HTTPProtocolType || listener.Protocol == gatewayv1.HTTPSProtocolType || listener.Protocol == gatewayv1.TLSProtocolType {\n\t\t\t\thostname := gatewayv1.Hostname(\"\")\n\t\t\t\tif listener.Hostname != nil {\n\t\t\t\t\thostname = *listener.Hostname\n\t\t\t\t}\n\n\t\t\t\tif conflictingListenerName, exists := seenHostnames[hostname]; exists {\n\t\t\t\t\tconflictedCondition := metav1.Condition{\n\t\t\t\t\t\tType:    string(gatewayv1.ListenerConditionConflicted),\n\t\t\t\t\t\tStatus:  metav1.ConditionTrue,\n\t\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonHostnameConflict),\n\t\t\t\t\t\tMessage: fmt.Sprintf(\"Hostname '%s' conflicts with another listener on the same port.\", hostname),\n\t\t\t\t\t}\n\t\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, conflictedCondition)\n\t\t\t\t\tsetListenerCondition(listenerConditions, conflictingListenerName, conflictedCondition)\n\t\t\t\t} else {\n\t\t\t\t\tseenHostnames[hostname] = listener.Name\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, listener := range gateway.Spec.Listeners {\n\t\t// If a listener is already conflicted, we don't need to check its secrets.\n\t\tif meta.IsStatusConditionTrue(listenerConditions[listener.Name], string(gatewayv1.ListenerConditionConflicted)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif listener.TLS == nil {\n\t\t\t// No TLS config, so no secrets to resolve. This listener is considered resolved.\n\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\tStatus:  metav1.ConditionTrue,\n\t\t\t\tReason:  string(gatewayv1.ListenerReasonResolvedRefs),\n\t\t\t\tMessage: \"All references resolved\",\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, certRef := range listener.TLS.CertificateRefs {\n\t\t\tif certRef.Group != nil && *certRef.Group != \"\" {\n\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\tStatus:  metav1.ConditionFalse,\n\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonInvalidCertificateRef),\n\t\t\t\t\tMessage: fmt.Sprintf(\"unsupported certificate ref grup: %s\", *certRef.Group),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif certRef.Kind != nil && *certRef.Kind != \"Secret\" {\n\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\tStatus:  metav1.ConditionFalse,\n\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonInvalidCertificateRef),\n\t\t\t\t\tMessage: fmt.Sprintf(\"unsupported certificate ref kind: %s\", *certRef.Kind),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tsecretNamespace := gateway.Namespace\n\t\t\tif certRef.Namespace != nil {\n\t\t\t\tsecretNamespace = string(*certRef.Namespace)\n\t\t\t}\n\n\t\t\tif secretNamespace != gateway.Namespace {\n\t\t\t\tfrom := gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\tGroup:     gatewayv1.GroupName,\n\t\t\t\t\tKind:      \"Gateway\",\n\t\t\t\t\tNamespace: gatewayv1.Namespace(gateway.Namespace),\n\t\t\t\t}\n\t\t\t\tto := gatewayv1.ReferenceGrantTo{\n\t\t\t\t\tGroup: \"\", // Core group for Secret\n\t\t\t\t\tKind:  \"Secret\",\n\t\t\t\t\tName:  &certRef.Name,\n\t\t\t\t}\n\t\t\t\tif !isCrossNamespaceRefAllowed(from, to, secretNamespace, c.referenceGrantLister) {\n\t\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\t\tStatus:  metav1.ConditionFalse,\n\t\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonRefNotPermitted),\n\t\t\t\t\t\tMessage: fmt.Sprintf(\"reference to Secret %s/%s not permitted by any ReferenceGrant\", secretNamespace, certRef.Name),\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsecret, err := c.secretLister.Secrets(secretNamespace).Get(string(certRef.Name))\n\t\t\tif err != nil {\n\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\tStatus:  metav1.ConditionFalse,\n\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonInvalidCertificateRef),\n\t\t\t\t\tMessage: fmt.Sprintf(\"reference to Secret %s/%s not found\", secretNamespace, certRef.Name),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif err := validateSecretCertificate(secret); err != nil {\n\t\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\t\tStatus:  metav1.ConditionFalse,\n\t\t\t\t\tReason:  string(gatewayv1.ListenerReasonInvalidCertificateRef),\n\t\t\t\t\tMessage: fmt.Sprintf(\"malformed Secret %s/%s : %v\", secretNamespace, certRef.Name, err.Error()),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Set the ResolvedRefs condition based on the outcome of the secret validation.\n\t\tif !meta.IsStatusConditionFalse(listenerConditions[listener.Name], string(gatewayv1.ListenerConditionResolvedRefs)) {\n\t\t\tsetListenerCondition(listenerConditions, listener.Name, metav1.Condition{\n\t\t\t\tType:    string(gatewayv1.ListenerConditionResolvedRefs),\n\t\t\t\tStatus:  metav1.ConditionTrue,\n\t\t\t\tReason:  string(gatewayv1.ListenerReasonResolvedRefs),\n\t\t\t\tMessage: \"All references resolved\",\n\t\t\t})\n\t\t}\n\t}\n\n\treturn listenerConditions\n}\n\nfunc (c *Controller) translateListenerToFilterChain(gateway *gatewayv1.Gateway, lis gatewayv1.Listener, virtualHosts []*routev3.VirtualHost, routeName string) (*listener.FilterChain, error) {\n\tvar filterChain *listener.FilterChain\n\n\tswitch lis.Protocol {\n\tcase gatewayv1.HTTPProtocolType, gatewayv1.HTTPSProtocolType:\n\t\trouterProto := &routerv3.Router{}\n\t\trouterAny, err := anypb.New(routerProto)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to marshal router config: %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\thcmConfig := &hcm.HttpConnectionManager{\n\t\t\tStatPrefix: string(lis.Name),\n\t\t\t// Enable X-Forwarded-For header\n\t\t\t// https://github.com/kubernetes-sigs/cloud-provider-kind/issues/296\n\t\t\tUseRemoteAddress: &wrapperspb.BoolValue{Value: true},\n\t\t\t// Support websocket upgrade\n\t\t\t// https://github.com/kubernetes-sigs/cloud-provider-kind/issues/355\n\t\t\tUpgradeConfigs: []*hcm.HttpConnectionManager_UpgradeConfig{{\n\t\t\t\tUpgradeType: \"websocket\",\n\t\t\t}},\n\t\t\tRouteSpecifier: &hcm.HttpConnectionManager_Rds{\n\t\t\t\tRds: &hcm.Rds{\n\t\t\t\t\tConfigSource: &corev3.ConfigSource{\n\t\t\t\t\t\tResourceApiVersion:    corev3.ApiVersion_V3,\n\t\t\t\t\t\tConfigSourceSpecifier: &corev3.ConfigSource_Ads{Ads: &corev3.AggregatedConfigSource{}},\n\t\t\t\t\t},\n\t\t\t\t\tRouteConfigName: routeName,\n\t\t\t\t},\n\t\t\t},\n\t\t\tHttpFilters: []*hcm.HttpFilter{{\n\t\t\t\tName: wellknown.Router,\n\t\t\t\tConfigType: &hcm.HttpFilter_TypedConfig{\n\t\t\t\t\tTypedConfig: routerAny,\n\t\t\t\t},\n\t\t\t}},\n\t\t}\n\t\thcmAny, err := anypb.New(hcmConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tfilterChain = &listener.FilterChain{\n\t\t\tFilters: []*listener.Filter{{\n\t\t\t\tName: wellknown.HTTPConnectionManager,\n\t\t\t\tConfigType: &listener.Filter_TypedConfig{\n\t\t\t\t\tTypedConfig: hcmAny,\n\t\t\t\t},\n\t\t\t}},\n\t\t}\n\n\tcase gatewayv1.TCPProtocolType, gatewayv1.TLSProtocolType:\n\t\t// TCP and TLS listeners require a TCP proxy filter.\n\t\t// We'll assume for now that routes for these are not supported and it's a direct pass-through.\n\t\ttcpProxy := &tcpproxyv3.TcpProxy{\n\t\t\tStatPrefix: string(lis.Name),\n\t\t\tClusterSpecifier: &tcpproxyv3.TcpProxy_Cluster{\n\t\t\t\tCluster: \"some_static_cluster\", // This needs to be determined from a TCPRoute/TLSRoute\n\t\t\t},\n\t\t}\n\t\ttcpProxyAny, err := anypb.New(tcpProxy)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfilterChain = &listener.FilterChain{\n\t\t\tFilters: []*listener.Filter{{\n\t\t\t\tName: wellknown.TCPProxy,\n\t\t\t\tConfigType: &listener.Filter_TypedConfig{\n\t\t\t\t\tTypedConfig: tcpProxyAny,\n\t\t\t\t},\n\t\t\t}},\n\t\t}\n\n\tcase gatewayv1.UDPProtocolType:\n\t\tudpProxy := &udpproxy.UdpProxyConfig{\n\t\t\tStatPrefix: string(lis.Name),\n\t\t\tRouteSpecifier: &udpproxy.UdpProxyConfig_Cluster{\n\t\t\t\tCluster: \"some_udp_cluster\", // This needs to be determined from a UDPRoute\n\t\t\t},\n\t\t}\n\t\tudpProxyAny, err := anypb.New(udpProxy)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfilterChain = &listener.FilterChain{\n\t\t\tFilters: []*listener.Filter{{\n\t\t\t\tName: \"envoy.filters.udp_listener.udp_proxy\",\n\t\t\t\tConfigType: &listener.Filter_TypedConfig{\n\t\t\t\t\tTypedConfig: udpProxyAny,\n\t\t\t\t},\n\t\t\t}},\n\t\t}\n\t}\n\n\t// Add SNI matching for applicable protocols\n\tif lis.Protocol == gatewayv1.HTTPSProtocolType || lis.Protocol == gatewayv1.TLSProtocolType {\n\t\tif lis.Hostname != nil && *lis.Hostname != \"\" {\n\t\t\tfilterChain.FilterChainMatch = &listener.FilterChainMatch{\n\t\t\t\tServerNames: []string{string(*lis.Hostname)},\n\t\t\t}\n\t\t}\n\t\t// Configure TLS context\n\t\ttlsContext, err := c.buildDownstreamTLSContext(context.Background(), gateway, lis)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to build TLS context for listener %s: %w\", lis.Name, err)\n\t\t}\n\t\tif tlsContext != nil {\n\t\t\tfilterChain.TransportSocket = &corev3.TransportSocket{\n\t\t\t\tName: \"envoy.transport_sockets.tls\",\n\t\t\t\tConfigType: &corev3.TransportSocket_TypedConfig{\n\t\t\t\t\tTypedConfig: tlsContext,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\treturn filterChain, nil\n}\n\nfunc (c *Controller) buildDownstreamTLSContext(ctx context.Context, gateway *gatewayv1.Gateway, lis gatewayv1.Listener) (*anypb.Any, error) {\n\tif lis.TLS == nil {\n\t\treturn nil, nil\n\t}\n\tif len(lis.TLS.CertificateRefs) == 0 {\n\t\treturn nil, fmt.Errorf(\"TLS is configured, but no certificate refs are provided\")\n\t}\n\n\ttlsContext := &tlsv3.DownstreamTlsContext{\n\t\tCommonTlsContext: &tlsv3.CommonTlsContext{\n\t\t\tTlsCertificates: []*tlsv3.TlsCertificate{},\n\t\t},\n\t}\n\n\tfor _, certRef := range lis.TLS.CertificateRefs {\n\t\tif certRef.Group != nil && *certRef.Group != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"unsupported certificate ref group: %s\", *certRef.Group)\n\t\t}\n\t\tif certRef.Kind != nil && *certRef.Kind != \"Secret\" {\n\t\t\treturn nil, fmt.Errorf(\"unsupported certificate ref kind: %s\", *certRef.Kind)\n\t\t}\n\n\t\tsecretNamespace := gateway.Namespace\n\t\tif certRef.Namespace != nil {\n\t\t\tsecretNamespace = string(*certRef.Namespace)\n\t\t}\n\n\t\tsecretName := string(certRef.Name)\n\t\tsecret, err := c.secretLister.Secrets(secretNamespace).Get(secretName)\n\t\tif err != nil {\n\t\t\t// Per the spec, if the grant was missing, we must not reveal that the secret doesn't exist.\n\t\t\t// The error from the grant check above takes precedence.\n\t\t\treturn nil, fmt.Errorf(\"failed to get secret %s/%s: %w\", secretNamespace, secretName, err)\n\t\t}\n\n\t\ttlsCert, err := toEnvoyTlsCertificate(secret)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to convert secret to tls certificate: %v\", err)\n\t\t}\n\t\ttlsContext.CommonTlsContext.TlsCertificates = append(tlsContext.CommonTlsContext.TlsCertificates, tlsCert)\n\t}\n\n\tany, err := anypb.New(tlsContext)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn any, nil\n}\n\nfunc validateSecretCertificate(secret *corev1.Secret) error {\n\tprivateKey, ok := secret.Data[corev1.TLSPrivateKeyKey]\n\tif !ok {\n\t\treturn fmt.Errorf(\"secret %s/%s does not contain key %s\", secret.Namespace, secret.Name, corev1.TLSPrivateKeyKey)\n\t}\n\tblock, _ := pem.Decode(privateKey)\n\tif block == nil {\n\t\treturn fmt.Errorf(\"secret %s/%s key %s does not contain a valid PEM-encoded private key\", secret.Namespace, secret.Name, corev1.TLSPrivateKeyKey)\n\t}\n\n\tcertChain, ok := secret.Data[corev1.TLSCertKey]\n\tif !ok {\n\t\treturn fmt.Errorf(\"secret %s/%s does not contain key %s\", secret.Namespace, secret.Name, corev1.TLSCertKey)\n\t}\n\tblock, _ = pem.Decode(certChain)\n\tif block == nil {\n\t\treturn fmt.Errorf(\"secret %s/%s key %s does not contain a valid PEM-encoded certificate chain\", secret.Namespace, secret.Name, corev1.TLSCertKey)\n\t}\n\treturn nil\n}\n\nfunc toEnvoyTlsCertificate(secret *corev1.Secret) (*tlsv3.TlsCertificate, error) {\n\tprivateKey, ok := secret.Data[corev1.TLSPrivateKeyKey]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"secret %s/%s does not contain key %s\", secret.Namespace, secret.Name, corev1.TLSPrivateKeyKey)\n\t}\n\tblock, _ := pem.Decode(privateKey)\n\tif block == nil {\n\t\treturn nil, fmt.Errorf(\"secret %s/%s key %s does not contain a valid PEM-encoded private key\", secret.Namespace, secret.Name, corev1.TLSPrivateKeyKey)\n\t}\n\n\tcertChain, ok := secret.Data[corev1.TLSCertKey]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"secret %s/%s does not contain key %s\", secret.Namespace, secret.Name, corev1.TLSCertKey)\n\t}\n\tblock, _ = pem.Decode(certChain)\n\tif block == nil {\n\t\treturn nil, fmt.Errorf(\"secret %s/%s key %s does not contain a valid PEM-encoded certificate chain\", secret.Namespace, secret.Name, corev1.TLSCertKey)\n\t}\n\n\treturn &tlsv3.TlsCertificate{\n\t\tCertificateChain: &corev3.DataSource{\n\t\t\tSpecifier: &corev3.DataSource_InlineBytes{\n\t\t\t\tInlineBytes: certChain,\n\t\t\t},\n\t\t},\n\t\tPrivateKey: &corev3.DataSource{\n\t\t\tSpecifier: &corev3.DataSource_InlineBytes{\n\t\t\t\tInlineBytes: privateKey,\n\t\t\t},\n\t\t},\n\t}, nil\n}\n\nfunc createEnvoyAddress(port uint32) *corev3.Address {\n\treturn &corev3.Address{\n\t\tAddress: &corev3.Address_SocketAddress{\n\t\t\tSocketAddress: &corev3.SocketAddress{\n\t\t\t\tProtocol: corev3.SocketAddress_TCP,\n\t\t\t\tAddress:  \"0.0.0.0\",\n\t\t\t\tPortSpecifier: &corev3.SocketAddress_PortValue{\n\t\t\t\t\tPortValue: port,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc createListenerFilters() []*listener.ListenerFilter {\n\ttlsInspectorConfig, _ := anypb.New(&tlsinspector.TlsInspector{})\n\treturn []*listener.ListenerFilter{\n\t\t{\n\t\t\tName: wellknown.TlsInspector,\n\t\t\tConfigType: &listener.ListenerFilter_TypedConfig{\n\t\t\t\tTypedConfig: tlsInspectorConfig,\n\t\t\t},\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/gateway/referencegrant.go",
    "content": "package gateway\n\nimport (\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/klog/v2\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n\tgatewayv1listers \"sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1\"\n)\n\n// isCrossNamespaceRefAllowed checks if a cross-namespace reference from a 'from' object\n// to a 'to' object is permitted by a ReferenceGrant in the 'to' object's namespace.\nfunc isCrossNamespaceRefAllowed(\n\tfrom gatewayv1.ReferenceGrantFrom, // Describes the referencing object (e.g., an HTTPRoute)\n\tto gatewayv1.ReferenceGrantTo, // Describes the referenced object (e.g., a Service)\n\ttoNamespace string, // The namespace of the referenced object\n\treferenceGrantLister gatewayv1listers.ReferenceGrantLister,\n) bool {\n\t// List all ReferenceGrants in the target namespace.\n\tgrants, err := referenceGrantLister.ReferenceGrants(toNamespace).List(labels.Everything())\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to list ReferenceGrants in namespace %s: %v\", toNamespace, err)\n\t\treturn false\n\t}\n\n\tfor _, grant := range grants {\n\t\t// Check if the grant's \"From\" section matches our referencing object.\n\t\tfromAllowed := false\n\t\tfor _, grantFrom := range grant.Spec.From {\n\t\t\tif grantFrom.Group == from.Group &&\n\t\t\t\tgrantFrom.Kind == from.Kind &&\n\t\t\t\tgrantFrom.Namespace == from.Namespace {\n\t\t\t\tfromAllowed = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !fromAllowed {\n\t\t\tcontinue // This grant doesn't apply to our 'from' object.\n\t\t}\n\n\t\t// Check if the grant's \"To\" section matches our referenced object.\n\t\ttoAllowed := false\n\t\tfor _, grantTo := range grant.Spec.To {\n\t\t\tif grantTo.Group == to.Group && grantTo.Kind == to.Kind {\n\t\t\t\t// If the grant specifies a resource name, it must match.\n\t\t\t\tif grantTo.Name == nil || *grantTo.Name == \"\" {\n\t\t\t\t\ttoAllowed = true // Grant applies to all resources of this kind.\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif to.Name != nil && *grantTo.Name == *to.Name {\n\t\t\t\t\ttoAllowed = true // Grant applies to this specific resource name.\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif toAllowed {\n\t\t\t// We found a grant that explicitly allows this cross-namespace reference.\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// No grant was found that allows this reference.\n\treturn false\n}\n"
  },
  {
    "path": "pkg/gateway/referencegrant_test.go",
    "content": "package gateway\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n\tgatewayv1listers \"sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1\"\n)\n\n// fakeReferenceGrantLister is a mock implementation of ReferenceGrantLister for testing.\ntype fakeReferenceGrantLister struct {\n\tgrants []*gatewayv1.ReferenceGrant\n\terr    error\n}\n\n// newFakeReferenceGrantLister creates a new fakeReferenceGrantLister.\nfunc newFakeReferenceGrantLister(grants []*gatewayv1.ReferenceGrant, err error) gatewayv1listers.ReferenceGrantLister {\n\treturn &fakeReferenceGrantLister{grants: grants, err: err}\n}\n\n// List returns the stored grants or an error.\nfunc (f *fakeReferenceGrantLister) List(selector labels.Selector) ([]*gatewayv1.ReferenceGrant, error) {\n\tif f.err != nil {\n\t\treturn nil, f.err\n\t}\n\treturn f.grants, nil\n}\n\n// Get returns the grant with the given name or an error.\nfunc (f *fakeReferenceGrantLister) Get(name string) (*gatewayv1.ReferenceGrant, error) {\n\tif f.err != nil {\n\t\treturn nil, f.err\n\t}\n\tfor _, grant := range f.grants {\n\t\tif grant.Name == name {\n\t\t\treturn grant, nil\n\t\t}\n\t}\n\treturn nil, errors.New(\"not found\")\n}\n\n// ReferenceGrants returns a lister for a specific namespace.\nfunc (f *fakeReferenceGrantLister) ReferenceGrants(namespace string) gatewayv1listers.ReferenceGrantNamespaceLister {\n\t// For testing purposes, we can return the lister itself, as we don't use the namespace in the mock List.\n\t// A more sophisticated mock could filter by namespace here.\n\treturn f\n}\n\nfunc TestIsCrossNamespaceRefAllowed(t *testing.T) {\n\tserviceKind := gatewayv1.Kind(\"Service\")\n\thttpRouteKind := gatewayv1.Kind(\"HTTPRoute\")\n\tgatewayGroup := gatewayv1.Group(\"gateway.networking.k8s.io\")\n\tcoreGroup := gatewayv1.Group(\"\")\n\n\tspecificServiceName := gatewayv1.ObjectName(\"specific-service\")\n\n\ttestCases := []struct {\n\t\tname        string\n\t\tfrom        gatewayv1.ReferenceGrantFrom\n\t\tto          gatewayv1.ReferenceGrantTo\n\t\ttoNamespace string\n\t\tgrants      []*gatewayv1.ReferenceGrant\n\t\tlisterError error\n\t\texpected    bool\n\t}{\n\t\t{\n\t\t\tname: \"allowed by grant\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants: []*gatewayv1.ReferenceGrant{\n\t\t\t\t{\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: httpRouteKind, Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname: \"allowed by grant with specific resource name\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t\tName:  &specificServiceName,\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants: []*gatewayv1.ReferenceGrant{\n\t\t\t\t{\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: httpRouteKind, Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind, Name: &specificServiceName},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname: \"denied because from namespace does not match\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"another-ns\", // Mismatch\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants: []*gatewayv1.ReferenceGrant{\n\t\t\t\t{\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: httpRouteKind, Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname: \"denied because to kind does not match\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  \"Secret\", // Mismatch\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants: []*gatewayv1.ReferenceGrant{\n\t\t\t\t{\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: httpRouteKind, Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname: \"denied because specific resource name does not match\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t\tName:  func() *gatewayv1.ObjectName { s := gatewayv1.ObjectName(\"other-service\"); return &s }(),\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants: []*gatewayv1.ReferenceGrant{\n\t\t\t\t{\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: httpRouteKind, Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind, Name: &specificServiceName},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname: \"no grants in namespace\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants:      []*gatewayv1.ReferenceGrant{},\n\t\t\texpected:    false,\n\t\t},\n\t\t{\n\t\t\tname: \"lister returns error\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants:      nil,\n\t\t\tlisterError: errors.New(\"failed to list\"),\n\t\t\texpected:    false,\n\t\t},\n\t\t{\n\t\t\tname: \"multiple grants, one allows\",\n\t\t\tfrom: gatewayv1.ReferenceGrantFrom{\n\t\t\t\tGroup:     gatewayGroup,\n\t\t\t\tKind:      httpRouteKind,\n\t\t\t\tNamespace: \"default\",\n\t\t\t},\n\t\t\tto: gatewayv1.ReferenceGrantTo{\n\t\t\t\tGroup: coreGroup,\n\t\t\t\tKind:  serviceKind,\n\t\t\t},\n\t\t\ttoNamespace: \"backend-ns\",\n\t\t\tgrants: []*gatewayv1.ReferenceGrant{\n\t\t\t\t{ // This one doesn't match\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: \"OtherKind\", Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ // This one matches\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Namespace: \"backend-ns\"},\n\t\t\t\t\tSpec: gatewayv1.ReferenceGrantSpec{\n\t\t\t\t\t\tFrom: []gatewayv1.ReferenceGrantFrom{\n\t\t\t\t\t\t\t{Group: gatewayGroup, Kind: httpRouteKind, Namespace: \"default\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: []gatewayv1.ReferenceGrantTo{\n\t\t\t\t\t\t\t{Group: coreGroup, Kind: serviceKind},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tlister := newFakeReferenceGrantLister(tc.grants, tc.listerError)\n\t\t\tresult := isCrossNamespaceRefAllowed(tc.from, tc.to, tc.toNamespace, lister)\n\t\t\tif result != tc.expected {\n\t\t\t\tt.Errorf(\"expected %v, but got %v\", tc.expected, result)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/gateway/routeadder/README.md",
    "content": "\nPackages generated with `hack/build-route-adder.sh` to inject a binary on the\nenvoy container image that allows to configure routes.\n\nThis is required because the envoy image does not have `route` or `iproute2`\ncommands and, in order to forward the gateway traffic to a Service ClusterIP, we\nneed to route it through one of the cluster nodes."
  },
  {
    "path": "pkg/gateway/routes.go",
    "content": "package gateway\n\nimport (\n\t\"strings\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\tcorev1listers \"k8s.io/client-go/listers/core/v1\"\n\t\"k8s.io/klog/v2\"\n\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n// isAllowedByListener checks if a given route is allowed to attach to a listener\n// based on the listener's `allowedRoutes` specification for namespaces and kinds.\nfunc isAllowedByListener(gateway *gatewayv1.Gateway, listener gatewayv1.Listener, route metav1.Object, namespaceLister corev1listers.NamespaceLister) bool {\n\tallowed := listener.AllowedRoutes\n\tif allowed == nil {\n\t\t// If AllowedRoutes is not set, only routes in the same namespace are allowed.\n\t\treturn route.GetNamespace() == gateway.GetNamespace()\n\t}\n\n\trouteNamespace := route.GetNamespace()\n\tgatewayNamespace := gateway.GetNamespace()\n\n\t// Check if the route's namespace is allowed.\n\tnamespaceAllowed := false\n\teffectiveFrom := gatewayv1.NamespacesFromSame\n\tif allowed.Namespaces != nil && allowed.Namespaces.From != nil {\n\t\teffectiveFrom = *allowed.Namespaces.From\n\t}\n\n\tswitch effectiveFrom {\n\tcase gatewayv1.NamespacesFromAll:\n\t\tnamespaceAllowed = true\n\tcase gatewayv1.NamespacesFromSame:\n\t\tnamespaceAllowed = (routeNamespace == gatewayNamespace)\n\tcase gatewayv1.NamespacesFromSelector:\n\t\tif allowed.Namespaces.Selector == nil {\n\t\t\tklog.Errorf(\"Invalid AllowedRoutes: Namespaces.From is 'Selector' but Namespaces.Selector is nil for Gateway %s/%s, Listener %s\", gatewayNamespace, gateway.GetName(), listener.Name)\n\t\t\treturn false\n\t\t}\n\t\tif namespaceLister == nil {\n\t\t\tklog.Warningf(\"Namespace selection using 'Selector' requires a Namespace Lister, but none was provided. Denying route %s/%s.\", routeNamespace, route.GetName())\n\t\t\treturn false\n\t\t}\n\t\tselector, err := metav1.LabelSelectorAsSelector(allowed.Namespaces.Selector)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to parse label selector for Gateway %s/%s, Listener %s: %v\", gatewayNamespace, gateway.GetName(), listener.Name, err)\n\t\t\treturn false\n\t\t}\n\t\trouteNsObj, err := namespaceLister.Get(routeNamespace)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Failed to get namespace %s for route %s/%s: %v\", routeNamespace, routeNamespace, route.GetName(), err)\n\t\t\treturn false\n\t\t}\n\t\tnamespaceAllowed = selector.Matches(labels.Set(routeNsObj.GetLabels()))\n\tdefault:\n\t\tklog.Errorf(\"Unknown 'From' value %q in AllowedRoutes.Namespaces for Gateway %s/%s, Listener %s\", effectiveFrom, gatewayNamespace, gateway.GetName(), listener.Name)\n\t\treturn false\n\t}\n\n\tif !namespaceAllowed {\n\t\treturn false\n\t}\n\n\t// If namespaces are allowed, check if the route's kind is allowed.\n\tif len(allowed.Kinds) == 0 {\n\t\t// No kinds specified, so all kinds are allowed.\n\t\treturn true\n\t}\n\n\tvar routeGroup, routeKind string\n\tswitch route.(type) {\n\tcase *gatewayv1.HTTPRoute:\n\t\trouteGroup = gatewayv1.GroupName\n\t\trouteKind = \"HTTPRoute\"\n\tcase *gatewayv1.GRPCRoute:\n\t\trouteGroup = gatewayv1.GroupName\n\t\trouteKind = \"GRPCRoute\"\n\tdefault:\n\t\tklog.Warningf(\"Cannot determine GroupKind for route object type %T for route %s/%s\", route, routeNamespace, route.GetName())\n\t\treturn false\n\t}\n\n\tfor _, allowedKind := range allowed.Kinds {\n\t\tallowedGroup := gatewayv1.Group(gatewayv1.GroupName)\n\t\tif allowedKind.Group != nil && *allowedKind.Group != \"\" {\n\t\t\tallowedGroup = *allowedKind.Group\n\t\t}\n\t\tif routeKind == string(allowedKind.Kind) && routeGroup == string(allowedGroup) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// The route's kind is not in the allowed list.\n\treturn false\n}\n\n// isAllowedByHostname checks if a route is allowed to attach to a listener\n// based on hostname matching rules.\nfunc isAllowedByHostname(listener gatewayv1.Listener, route metav1.Object) bool {\n\t// If the listener specifies no hostname, it allows all route hostnames.\n\tif listener.Hostname == nil || *listener.Hostname == \"\" {\n\t\treturn true\n\t}\n\tlistenerHostname := string(*listener.Hostname)\n\n\tvar routeHostnames []gatewayv1.Hostname\n\tswitch r := route.(type) {\n\tcase *gatewayv1.HTTPRoute:\n\t\trouteHostnames = r.Spec.Hostnames\n\tcase *gatewayv1.GRPCRoute:\n\t\trouteHostnames = r.Spec.Hostnames\n\tdefault:\n\t\t// Not a type with hostnames, so no hostname check needed.\n\t\treturn true\n\t}\n\n\t// If the route specifies no hostnames, it inherits from the listener, which is always valid.\n\tif len(routeHostnames) == 0 {\n\t\treturn true\n\t}\n\n\t// If the route specifies hostnames, at least one must be permitted by the listener.\n\tfor _, routeHostname := range routeHostnames {\n\t\tif isHostnameSubset(string(routeHostname), listenerHostname) {\n\t\t\t// Found a valid hostname match. The route is allowed by this listener.\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// If we reach here, the route specified hostnames, but NONE of them were valid\n\t// for this listener. The route must not be attached.\n\treturn false\n}\n\n// getIntersectingHostnames calculates the precise set of hostnames for an Envoy VirtualHost,\n// resolving each match to the most restrictive hostname as per the Gateway API specification.\n// It returns a slice of the resulting hostnames, or an empty slice if there is no valid intersection.\nfunc getIntersectingHostnames(listener gatewayv1.Listener, routeHostnames []gatewayv1.Hostname) []string {\n\t// Case 1: The listener has no hostname specified. It acts as a universal wildcard,\n\t// allowing any and all hostnames from the route.\n\tif listener.Hostname == nil || *listener.Hostname == \"\" {\n\t\tif len(routeHostnames) == 0 {\n\t\t\treturn []string{\"*\"} // Universal match\n\t\t}\n\t\t// The result is simply the route's own hostnames.\n\t\tvar names []string\n\t\tfor _, h := range routeHostnames {\n\t\t\tnames = append(names, string(h))\n\t\t}\n\t\treturn names\n\t}\n\tlistenerHostname := string(*listener.Hostname)\n\n\t// Case 2: The route has no hostnames. It implicitly inherits the listener's specific hostname.\n\tif len(routeHostnames) == 0 {\n\t\treturn []string{listenerHostname}\n\t}\n\n\t// Case 3: Both have hostnames. We must find the intersection and then determine\n\t// the most restrictive hostname for each match.\n\tintersection := sets.New[string]()\n\tfor _, h := range routeHostnames {\n\t\trouteHostname := string(h)\n\t\tif isHostnameSubset(routeHostname, listenerHostname) {\n\t\t\t// A valid intersection was found. Now, determine the most specific\n\t\t\t// hostname to use for the configuration.\n\t\t\tif strings.HasPrefix(routeHostname, \"*\") && !strings.HasPrefix(listenerHostname, \"*\") {\n\t\t\t\t// If the route is a wildcard and the listener is specific, the listener's\n\t\t\t\t// specific hostname is the most restrictive result.\n\t\t\t\tintersection.Insert(listenerHostname)\n\t\t\t} else {\n\t\t\t\t// In all other valid cases (exact match, specific route on a wildcard listener),\n\t\t\t\t// the route's hostname is the most restrictive result.\n\t\t\t\tintersection.Insert(routeHostname)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the unique set of resulting hostnames.\n\treturn intersection.UnsortedList()\n}\n\n// isHostnameSubset checks if a route hostname is a valid subset of a listener hostname,\n// implementing the precise matching rules from the Gateway API specification.\nfunc isHostnameSubset(routeHostname, listenerHostname string) bool {\n\t// Rule 1: An exact match is always a valid intersection.\n\tif routeHostname == listenerHostname {\n\t\treturn true\n\t}\n\n\t// Rule 2: Listener has a wildcard (e.g., \"*.example.com\").\n\tif strings.HasPrefix(listenerHostname, \"*.\") {\n\t\t// Use the part of the string including the dot as the suffix.\n\t\tlistenerSuffix := listenerHostname[1:] // e.g., \".example.com\"\n\n\t\t// Case 2a: Route also has a wildcard (e.g., \"*.foo.example.com\").\n\t\t// The route's suffix must be identical to or a sub-suffix of the listener's.\n\t\tif strings.HasPrefix(routeHostname, \"*.\") {\n\t\t\trouteSuffix := routeHostname[1:] // e.g., \".foo.example.com\"\n\t\t\treturn strings.HasSuffix(routeSuffix, listenerSuffix)\n\t\t}\n\n\t\t// Case 2b: Route is specific (e.g., \"foo.example.com\").\n\t\t// The route must end with the listener's suffix. This correctly handles\n\t\t// the \"parent domain\" case because \"example.com\" does not have the\n\t\t// suffix \".example.com\".\n\t\treturn strings.HasSuffix(routeHostname, listenerSuffix)\n\t}\n\n\t// Rule 3: Route has a wildcard (e.g., \"*.example.com\").\n\tif strings.HasPrefix(routeHostname, \"*.\") {\n\t\trouteSuffix := routeHostname[1:] // e.g., \".example.com\"\n\t\trouteDomain := routeHostname[2:] // e.g., \"example.com\"\n\n\t\t// The listener must be more specific (not a wildcard).\n\t\tif !strings.HasPrefix(listenerHostname, \"*.\") {\n\t\t\t// The listener hostname must be the parent domain or a subdomain.\n\t\t\t// e.g., \"example.com\" or \"foo.example.com\" are subsets of \"*.example.com\".\n\t\t\treturn listenerHostname == routeDomain || strings.HasSuffix(listenerHostname, routeSuffix)\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "pkg/gateway/routes_test.go",
    "content": "package gateway\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\tcorev1listers \"k8s.io/client-go/listers/core/v1\"\n\t\"k8s.io/utils/ptr\"\n\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n)\n\n// A mock implementation of NamespaceLister for testing purposes.\ntype mockNamespaceLister struct {\n\tnamespaces map[string]*corev1.Namespace\n}\n\nfunc (m *mockNamespaceLister) List(selector labels.Selector) ([]*corev1.Namespace, error) {\n\tvar matching []*corev1.Namespace\n\tfor _, ns := range m.namespaces {\n\t\tif selector.Matches(labels.Set(ns.Labels)) {\n\t\t\tmatching = append(matching, ns)\n\t\t}\n\t}\n\treturn matching, nil\n}\n\nfunc (m *mockNamespaceLister) Get(name string) (*corev1.Namespace, error) {\n\tif ns, ok := m.namespaces[name]; ok {\n\t\treturn ns, nil\n\t}\n\treturn nil, fmt.Errorf(\"namespace %s not found\", name)\n}\n\nfunc (m *mockNamespaceLister) GetPodNamespaces(pod *corev1.Pod) ([]*corev1.Namespace, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockNamespaceLister) Pods(namespace string) corev1listers.PodNamespaceLister {\n\treturn nil\n}\n\nfunc TestIsAllowedByListener(t *testing.T) {\n\ttestGateway := &gatewayv1.Gateway{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      \"test-gateway\",\n\t\t\tNamespace: \"gateway-ns\",\n\t\t},\n\t}\n\n\thttpRouteKind := gatewayv1.RouteGroupKind{Kind: \"HTTPRoute\"}\n\tgrpcRouteKind := gatewayv1.RouteGroupKind{Group: ptr.To(gatewayv1.Group(gatewayv1.GroupName)), Kind: \"GRPCRoute\"}\n\totherRouteKind := gatewayv1.RouteGroupKind{Group: ptr.To(gatewayv1.Group(\"other.group\")), Kind: \"OtherRoute\"}\n\n\tmockNsLister := &mockNamespaceLister{\n\t\tnamespaces: map[string]*corev1.Namespace{\n\t\t\t\"gateway-ns\": {ObjectMeta: metav1.ObjectMeta{Name: \"gateway-ns\", Labels: map[string]string{\"type\": \"gateway\"}}},\n\t\t\t\"route-ns-1\": {ObjectMeta: metav1.ObjectMeta{Name: \"route-ns-1\", Labels: map[string]string{\"app\": \"foo\"}}},\n\t\t\t\"route-ns-2\": {ObjectMeta: metav1.ObjectMeta{Name: \"route-ns-2\", Labels: map[string]string{\"app\": \"bar\"}}},\n\t\t},\n\t}\n\n\ttests := []struct {\n\t\tname          string\n\t\tlistener      gatewayv1.Listener\n\t\troute         metav1.Object\n\t\tnamespaceList corev1listers.NamespaceLister // Use the interface type\n\t\twant          bool\n\t}{\n\t\t{\n\t\t\tname: \"Nil AllowedRoutes, route in same namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:          \"listener-1\",\n\t\t\t\tAllowedRoutes: nil, // Default should be Same namespace\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"gateway-ns\"}, // Same ns\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true,\n\t\t},\n\t\t{\n\t\t\tname: \"Nil AllowedRoutes, route in different namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:          \"listener-1\",\n\t\t\t\tAllowedRoutes: nil, // Default should be Same namespace\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"other-ns\"}, // Different ns\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false,\n\t\t},\n\t\t{\n\t\t\tname: \"NamespacesFromSame, route in same namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromSame)},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"gateway-ns\"}, // Same ns\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true,\n\t\t},\n\t\t{\n\t\t\tname: \"NamespacesFromSame, route in different namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromSame)},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"other-ns\"}, // Different ns\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false,\n\t\t},\n\t\t{\n\t\t\tname: \"NamespacesFromAll, route in different namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromAll)},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"other-ns\"}, // Different ns\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true,\n\t\t},\n\t\t{\n\t\t\tname: \"NamespacesFromSelector, matching namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{\n\t\t\t\t\t\tFrom:     ptr.To(gatewayv1.NamespacesFromSelector),\n\t\t\t\t\t\tSelector: &metav1.LabelSelector{MatchLabels: map[string]string{\"app\": \"foo\"}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"route-ns-1\"}, // Matches selector\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true,\n\t\t},\n\t\t{\n\t\t\tname: \"NamespacesFromSelector, non-matching namespace\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{\n\t\t\t\t\t\tFrom:     ptr.To(gatewayv1.NamespacesFromSelector),\n\t\t\t\t\t\tSelector: &metav1.LabelSelector{MatchLabels: map[string]string{\"app\": \"foo\"}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"route-ns-2\"}, // Does not match selector\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false,\n\t\t},\n\t\t{\n\t\t\tname: \"NamespacesFromSelector, namespace not found\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{\n\t\t\t\t\t\tFrom:     ptr.To(gatewayv1.NamespacesFromSelector),\n\t\t\t\t\t\tSelector: &metav1.LabelSelector{MatchLabels: map[string]string{\"app\": \"foo\"}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"non-existent-ns\"}, // NS doesn't exist\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false,\n\t\t},\n\t\t{\n\t\t\tname: \"Allowed Kind matches HTTPRoute (default group)\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromAll)},\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{httpRouteKind},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true,\n\t\t},\n\t\t{\n\t\t\tname: \"Allowed Kind matches GRPCRoute (explicit group)\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromAll)},\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{grpcRouteKind},\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.GRPCRoute{ // GRPCRoute type\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true,\n\t\t},\n\t\t{\n\t\t\tname: \"Allowed Kind does not match route kind\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromAll)},\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{grpcRouteKind}, // Only allow GRPCRoute\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{ // Route is HTTPRoute\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false,\n\t\t},\n\t\t{\n\t\t\tname: \"Allowed Kind does not match route group\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromAll)},\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{otherRouteKind}, // Allow other.group/OtherRoute\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{ // Route is gateway.networking.k8s.io/HTTPRoute\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false,\n\t\t},\n\t\t{\n\t\t\tname: \"Empty Kinds list allows compatible kinds (HTTPRoute)\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromAll)},\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{}, // Empty list\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          true, // Namespace check passes, empty Kinds passes\n\t\t},\n\t\t{\n\t\t\tname: \"Namespace allowed, Kind denied\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromSame)}, // Same NS allowed\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{grpcRouteKind},                              // Only GRPCRoute allowed\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{ // HTTPRoute in same NS\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"gateway-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false, // Kind check fails\n\t\t},\n\t\t{\n\t\t\tname: \"Namespace denied, Kind allowed\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName: \"listener-1\",\n\t\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{From: ptr.To(gatewayv1.NamespacesFromSame)}, // Same NS allowed\n\t\t\t\t\tKinds:      []gatewayv1.RouteGroupKind{httpRouteKind},                              // HTTPRoute allowed\n\t\t\t\t},\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{ // HTTPRoute in different NS\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"other-ns\"},\n\t\t\t},\n\t\t\tnamespaceList: mockNsLister,\n\t\t\twant:          false, // Namespace check fails\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := isAllowedByListener(testGateway, tt.listener, tt.route, tt.namespaceList); got != tt.want {\n\t\t\t\tt.Errorf(\"isAllowedByListener() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsAllowedByHostname(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tlistener gatewayv1.Listener\n\t\troute    metav1.Object\n\t\twant     bool\n\t}{\n\t\t{\n\t\t\tname: \"Listener has no hostname, allows any route hostname\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: nil,\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{\"foo.example.com\"}},\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Route has no hostname, inherits from listener\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"bar.example.com\")),\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{}},\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Exact match\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"foo.example.com\")),\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{\"foo.example.com\"}},\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard listener, subdomain route\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{\"foo.example.com\"}},\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"No match\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"foo.example.com\")),\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{\"bar.example.com\"}},\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard listener, non-matching route\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{\"foo.another.com\"}},\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard listener, parent domain route (not allowed)\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\troute: &gatewayv1.HTTPRoute{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"route1\", Namespace: \"any-ns\"},\n\t\t\t\tSpec:       gatewayv1.HTTPRouteSpec{Hostnames: []gatewayv1.Hostname{\"example.com\"}},\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := isAllowedByHostname(tt.listener, tt.route); got != tt.want {\n\t\t\t\tt.Errorf(\"isAllowedByHostname() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsHostnameSubset(t *testing.T) {\n\t// Test cases are derived directly from the Gateway API specification\n\t// for hostname matching.\n\ttestCases := []struct {\n\t\tname             string\n\t\tlistenerHostname string\n\t\trouteHostname    string\n\t\twant             bool\n\t}{\n\t\t// --- Core Scenarios from Spec ---\n\t\t{\n\t\t\tname:             \"Spec: Exact match\",\n\t\t\tlistenerHostname: \"test.example.com\",\n\t\t\trouteHostname:    \"test.example.com\",\n\t\t\twant:             true,\n\t\t},\n\t\t{\n\t\t\tname:             \"Spec: Wildcard route matches specific listener\",\n\t\t\tlistenerHostname: \"test.example.com\",\n\t\t\trouteHostname:    \"*.example.com\",\n\t\t\twant:             true,\n\t\t},\n\t\t{\n\t\t\tname:             \"Spec: Specific route matches wildcard listener\",\n\t\t\tlistenerHostname: \"*.example.com\",\n\t\t\trouteHostname:    \"test.example.com\",\n\t\t\twant:             true,\n\t\t},\n\t\t{\n\t\t\tname:             \"Spec: Multi-level specific route matches wildcard listener\",\n\t\t\tlistenerHostname: \"*.example.com\",\n\t\t\trouteHostname:    \"foo.test.example.com\",\n\t\t\twant:             true,\n\t\t},\n\t\t{\n\t\t\tname:             \"Spec: Identical wildcards match\",\n\t\t\tlistenerHostname: \"*.example.com\",\n\t\t\trouteHostname:    \"*.example.com\",\n\t\t\twant:             true,\n\t\t},\n\n\t\t// --- Explicit \"Not Matching\" Scenarios from Spec ---\n\t\t{\n\t\t\tname:             \"Spec: Parent domain does not match wildcard listener\",\n\t\t\tlistenerHostname: \"*.example.com\",\n\t\t\trouteHostname:    \"example.com\",\n\t\t\twant:             false,\n\t\t},\n\t\t{\n\t\t\tname:             \"Spec: Different TLD does not match wildcard listener\",\n\t\t\tlistenerHostname: \"*.example.com\",\n\t\t\trouteHostname:    \"test.example.net\",\n\t\t\twant:             false,\n\t\t},\n\n\t\t// --- Additional Edge Cases ---\n\t\t{\n\t\t\tname:             \"Route with more specific wildcard matches listener\",\n\t\t\tlistenerHostname: \"*.example.com\",\n\t\t\trouteHostname:    \"*.foo.example.com\",\n\t\t\twant:             true,\n\t\t},\n\t\t{\n\t\t\tname:             \"Route with less specific wildcard does NOT match listener\",\n\t\t\tlistenerHostname: \"*.foo.example.com\",\n\t\t\trouteHostname:    \"*.example.com\",\n\t\t\twant:             false,\n\t\t},\n\t\t{\n\t\t\tname:             \"Mismatched specific hostnames\",\n\t\t\tlistenerHostname: \"foo.example.com\",\n\t\t\trouteHostname:    \"bar.example.com\",\n\t\t\twant:             false,\n\t\t},\n\t\t{\n\t\t\tname:             \"Wildcard route does not match different specific TLD\",\n\t\t\tlistenerHostname: \"foo.example.org\",\n\t\t\trouteHostname:    \"*.example.com\",\n\t\t\twant:             false,\n\t\t},\n\t\t{\n\t\t\tname:             \"Wildcard route does match specific TLD\",\n\t\t\tlistenerHostname: \"very.specific.com\",\n\t\t\trouteHostname:    \"*.specific.com\",\n\t\t\twant:             true,\n\t\t},\n\t\t{\n\t\t\tname:             \"Wildcard route does match partially\",\n\t\t\tlistenerHostname: \"*.specific.com\",\n\t\t\trouteHostname:    \"*.muchspecific.com\",\n\t\t\twant:             false,\n\t\t},\n\t\t{\n\t\t\tname:             \"Wildcard route does match partially\",\n\t\t\tlistenerHostname: \"*.muchspecific.com\",\n\t\t\trouteHostname:    \"*.specific.com\",\n\t\t\twant:             false,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tif got := isHostnameSubset(tc.routeHostname, tc.listenerHostname); got != tc.want {\n\t\t\t\tt.Errorf(\"isHostnameSubset(route: %q, listener: %q) = %v; want %v\", tc.routeHostname, tc.listenerHostname, got, tc.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetIntersectingHostnames(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\tlistener       gatewayv1.Listener\n\t\trouteHostnames []gatewayv1.Hostname\n\t\twant           []string\n\t}{\n\t\t{\n\t\t\tname: \"Listener has no hostname, route has none\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: nil,\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{},\n\t\t\twant:           []string{\"*\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Listener has no hostname, route has one\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: nil,\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"foo.example.com\"},\n\t\t\twant:           []string{\"foo.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Listener has no hostname, route has multiple\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: nil,\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"foo.example.com\", \"bar.example.com\"},\n\t\t\twant:           []string{\"foo.example.com\", \"bar.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Listener has specific hostname, route has none\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"listener.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{},\n\t\t\twant:           []string{\"listener.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Exact match\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"foo.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"foo.example.com\"},\n\t\t\twant:           []string{\"foo.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard listener, specific route\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"foo.example.com\"},\n\t\t\twant:           []string{\"foo.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Specific listener, wildcard route\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"foo.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"*.example.com\"},\n\t\t\t// The result is the listener's more specific hostname\n\t\t\twant: []string{\"foo.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard listener, more specific wildcard route\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"*.foo.example.com\"},\n\t\t\twant:           []string{\"*.foo.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"No intersection\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"a.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"b.com\"},\n\t\t\twant:           []string{},\n\t\t},\n\t\t{\n\t\t\tname: \"Multiple valid intersections\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"a.example.com\", \"b.example.com\", \"no.match.org\"},\n\t\t\twant:           []string{\"a.example.com\", \"b.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"Complex intersection with specific and wildcard\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.example.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"a.example.com\", \"*.b.example.com\", \"example.com\"},\n\t\t\t// \"example.com\" is not a valid subset\n\t\t\twant: []string{\"a.example.com\", \"*.b.example.com\"},\n\t\t},\n\t\t{\n\t\t\tname: \"No intersection wildcards are per path\",\n\t\t\tlistener: gatewayv1.Listener{\n\t\t\t\tName:     \"listener-1\",\n\t\t\t\tHostname: ptr.To(gatewayv1.Hostname(\"*.wildcard.com\")),\n\t\t\t},\n\t\t\trouteHostnames: []gatewayv1.Hostname{\"*.examplewildcard.com\", \"*.b.example.com\", \"example.com\"},\n\t\t\twant:           []string{},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := getIntersectingHostnames(tt.listener, tt.routeHostnames)\n\t\t\tif !equalUnordered(got, tt.want) {\n\t\t\t\tt.Errorf(\"getIntersectingHostnames() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// equalUnordered checks if two string slices are equal, ignoring order.\nfunc equalUnordered(a, b []string) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tm := make(map[string]int, len(a))\n\tfor _, v := range a {\n\t\tm[v]++\n\t}\n\tfor _, v := range b {\n\t\tif m[v] == 0 {\n\t\t\treturn false\n\t\t}\n\t\tm[v]--\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "pkg/ingress/README.md",
    "content": "# Ingress Controller (Ingress-to-Gateway Translation)\n\n\nThis is a Kubernetes controller that implements the `networkingv1.Ingress` API\nspecification.\n\nIts primary purpose is to act as a translation layer, not a data plane. It\nwatches `Ingress` resources and translates their semantics into `Gateway API`\nresources, specifically `Gateway` and `HTTPRoute`. The actual proxying and\ntraffic management can then be done by a separate, conformant `Gateway API`\nimplementation that reads these translated resources.\n\nThe controller's goal is to provide the exact semantics of the `Ingress` API\nusing a standard `Gateway API` data plane.\n\n\n## Architecture\n\nThe controller's logic is built on four key components that work together to\nmimic `Ingress` behavior.\n\n### Singleton Namespace Gateway\n\nThe controller ensures that a single `gatewayv1.Gateway` resource exists for\neach namespace that contains a managed `Ingress`.\n\nThis `Gateway` is given a predictable name (e.g., kind-ingress-gateway).\n\nIt acts as the single, consolidated entry point for all `Ingress` traffic within\nthat namespace.\n\nIt is configured with a `GatewayClassName` provided to the controller, which\nlinks it to the underlying `Gateway API` data plane implementation.\n\n### Ingress-to-HTTPRoute Translation (1:N Mapping)\n\nTo correctly implement `Ingress` precedence (where exact hosts and paths are\nmatched before wildcards or prefixes), the controller implements a 1-to-Many\n(1:N) mapping for each `Ingress` resource:\n\n* **Per-Host Rule:** For each rule defined in `ingress.spec.rules` (e.g., host:\n  \"foo.example.com\"), a dedicated `HTTPRoute` resource is created. This\n  `HTTPRoute` contains only the hostnames and rules (paths) for that specific\n  host. This design correctly isolates rules per host.\n\n* **Default Backend Rule:** A single, separate `HTTPRoute` is created to handle\n  the default backend. This route has its hostnames field omitted (nil), which\n  in `Gateway API` semantics means it matches all traffic that wasn't captured\n  by a more specific (per-host) `HTTPRoute`.\n\nPrecedence: The controller implements `Ingress` default backend precedence. If\nan `Ingress` defines a rule with an empty host (host: \"\"), that rule's paths are\nused for the default backend `HTTPRoute`. If no such rule exists, the\ningress.spec.defaultBackend is used as a fallback.\n\n### Namespace-Wide TLS Aggregation\n\nThe `Ingress` spec allows multiple `Ingress`es to provide TLS secrets. The\ncontroller consolidates this for the singleton Gateway.\n\nOn every reconciliation, the controller scans all managed `Ingress`es in the\nnamespace.\n\nIt aggregates every unique secretName from all ingress.spec.tls sections.\n\nThis combined, sorted list of secrets is set on the certificateRefs field of the\nsingleton Gateway's HTTPS listener.\n\nThis means all `Ingress`es in a namespace share one set of TLS certificates on a\nsingle listener, which is consistent with how `Ingress` is typically\nimplemented.\n\n### Ingress Status Reconciliation\n\nThe controller watches the status of the singleton namespace Gateway.\n\nWhen the underlying Gateway API implementation provisions an IP or hostname for\nthe Gateway, the controller detects this change.\n\nIt copies this IP/hostname to the `status.loadBalancer` field of every managed\n`Ingress` in that namespace.\n\n### Reconciliation Flow (syncHandler)\n\nThe simplified logic for a single `Ingress` change (Create, Update) is as\nfollows:\n\n1. An `Ingress` event is received for ingress-A in namespace-foo.\n\n2. The controller re-scans all `Ingress`es in namespace-foo to get a fresh,\n   aggregated list of all TLS secrets.\n\n3. It reconciles the singleton Gateway in namespace-foo, ensuring it exists and\n   its HTTPS listener has the correct (sorted) list of aggregated secrets.\n\n4. The controller generates a \"desired\" list of `HTTPRoute` resources for\n   ingress-A (e.g., one for a.example.com and one for the default backend).\n\n5. It lists all \"existing\" `HTTPRoute`s in namespace-foo that are owned by\n   ingress-A.\n\n6. It compares the \"desired\" and \"existing\" lists:\n\n7. New routes are created.\n\n8. Existing routes are updated if their spec (paths, backends) has changed.\n\n9. Stale routes (e.g., for a host that was removed from ingress-A) are deleted.\n\n10. The controller fetches the latest `Gateway.status` and updates\n    ingress-A.status (and all other Ingresses in the namespace) with the\n    provisioned IP/hostname.\n\n## Known Incompatibilities\n\nThis translation model is highly conformant but has known semantic mismatches\nwith the `Ingress` API, as identified by the `Ingress` conformance test suite.\n\nWildcard Host Matching: The `Ingress` API specifies that host: \"*.foo.com\"\nshould not match baz.bar.foo.com (it matches only one DNS label). The Gateway\nAPI specifies that hostnames: [\"*.foo.com\"] does match baz.bar.foo.com (it\nmatches all subdomains). This controller follows the Gateway API specification,\nas that is its underlying data plane."
  },
  {
    "path": "pkg/ingress/controller.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\" // New import\n\t\"encoding/hex\"  // New import\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\t\"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/runtime\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\tcorev1informers \"k8s.io/client-go/informers/core/v1\"\n\tnetworkingv1informers \"k8s.io/client-go/informers/networking/v1\"\n\t\"k8s.io/client-go/kubernetes\"\n\tcorelisters \"k8s.io/client-go/listers/core/v1\"\n\tnetworkinglisters \"k8s.io/client-go/listers/networking/v1\"\n\t\"k8s.io/client-go/tools/cache\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/ptr\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n\tgatewayclient \"sigs.k8s.io/gateway-api/pkg/client/clientset/versioned\"\n\tgatewayinformers \"sigs.k8s.io/gateway-api/pkg/client/informers/externalversions/apis/v1\"\n\tgatewaylisters \"sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1\"\n)\n\nconst (\n\t// IngressClassName is the name of the IngressClass resource\n\tIngressClassName = \"cloud-provider-kind\"\n\t// IngressClassController is the value of the spec.controller field\n\tIngressClassController = \"kind.sigs.k8s.io/ingress-controller\"\n\t// GatewayName is the well-defined name for the Gateway we create in each namespace\n\tGatewayName = \"kind-ingress-gateway\"\n)\n\n// Controller is the controller implementation for Ingress resources\ntype Controller struct {\n\tgatewayClassName string\n\tclientset        kubernetes.Interface\n\tgwClientset      gatewayclient.Interface\n\n\tingressLister   networkinglisters.IngressLister\n\tclassLister     networkinglisters.IngressClassLister\n\tserviceLister   corelisters.ServiceLister\n\tsecretLister    corelisters.SecretLister\n\thttpRouteLister gatewaylisters.HTTPRouteLister\n\tgatewayLister   gatewaylisters.GatewayLister\n\n\tingressSynced   cache.InformerSynced\n\tclassSynced     cache.InformerSynced\n\tserviceSynced   cache.InformerSynced\n\tsecretSynced    cache.InformerSynced\n\thttpRouteSynced cache.InformerSynced\n\tgatewaySynced   cache.InformerSynced\n\n\tisDefaultClass atomic.Bool\n\tworkqueue      workqueue.TypedRateLimitingInterface[string]\n}\n\n// NewController returns a new ingress controller\nfunc NewController(\n\tclientset kubernetes.Interface,\n\tgwClientset gatewayclient.Interface,\n\tgatewayClassName string, // Class for managed Gateways\n\tingressInformer networkingv1informers.IngressInformer,\n\tingressClassInformer networkingv1informers.IngressClassInformer,\n\tserviceInformer corev1informers.ServiceInformer, // Add Service informer\n\tsecretInformer corev1informers.SecretInformer, // Add Secret informer\n\thttpRouteInformer gatewayinformers.HTTPRouteInformer, // Add HTTPRoute informer\n\tgatewayInformer gatewayinformers.GatewayInformer, // Add Gateway informer\n) (*Controller, error) {\n\n\tcontroller := &Controller{\n\t\tclientset:        clientset,\n\t\tgwClientset:      gwClientset,\n\t\tgatewayClassName: gatewayClassName,\n\t\tingressLister:    ingressInformer.Lister(),\n\t\tclassLister:      ingressClassInformer.Lister(),\n\t\tserviceLister:    serviceInformer.Lister(),\n\t\tsecretLister:     secretInformer.Lister(),\n\t\thttpRouteLister:  httpRouteInformer.Lister(),\n\t\tgatewayLister:    gatewayInformer.Lister(),\n\t\tingressSynced:    ingressInformer.Informer().HasSynced,\n\t\tclassSynced:      ingressClassInformer.Informer().HasSynced,\n\t\tserviceSynced:    serviceInformer.Informer().HasSynced,\n\t\tsecretSynced:     secretInformer.Informer().HasSynced,\n\t\thttpRouteSynced:  httpRouteInformer.Informer().HasSynced,\n\t\tgatewaySynced:    gatewayInformer.Informer().HasSynced,\n\t\tworkqueue: workqueue.NewTypedRateLimitingQueueWithConfig(\n\t\t\tworkqueue.DefaultTypedControllerRateLimiter[string](),\n\t\t\tworkqueue.TypedRateLimitingQueueConfig[string]{Name: \"ingress\"},\n\t\t),\n\t}\n\n\tklog.Info(\"Setting up event handlers for Ingress controller\")\n\t// Watch Ingresses\n\t_, err := ingressInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc: controller.enqueueIngress,\n\t\tUpdateFunc: func(old, new interface{}) {\n\t\t\tcontroller.enqueueIngress(new)\n\t\t},\n\t\tDeleteFunc: controller.enqueueIngress,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Watch IngressClasses\n\t_, err = ingressClassInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc:    controller.handleIngressClass,\n\t\tUpdateFunc: func(old, new interface{}) { controller.handleIngressClass(new) },\n\t\tDeleteFunc: controller.handleIngressClass,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Watch Services\n\t_, err = serviceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc:    controller.handleObject,\n\t\tUpdateFunc: func(old, new interface{}) { controller.handleObject(new) },\n\t\tDeleteFunc: controller.handleObject,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Watch Secrets\n\t_, err = secretInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc:    controller.handleObject,\n\t\tUpdateFunc: func(old, new interface{}) { controller.handleObject(new) },\n\t\tDeleteFunc: controller.handleObject,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Watch HTTPRoutes\n\t_, err = httpRouteInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc: controller.enqueueIngressFromRoute,\n\t\tUpdateFunc: func(old, new interface{}) {\n\t\t\tcontroller.enqueueIngressFromRoute(new)\n\t\t},\n\t\tDeleteFunc: controller.enqueueIngressFromRoute,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Watch Gateways\n\t_, err = gatewayInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n\t\tAddFunc:    controller.handleGateway,\n\t\tUpdateFunc: func(old, new interface{}) { controller.handleGateway(new) },\n\t\tDeleteFunc: controller.handleGateway,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn controller, nil\n}\n\nfunc (c *Controller) Init(ctx context.Context) error {\n\tlogger := klog.FromContext(ctx).WithValues(\"controller\", \"ingress\", \"ingressClass\", IngressClassName)\n\n\t// Wait for the caches to be synced before starting workers\n\tlogger.Info(\"Waiting for informer caches to sync\")\n\tif !cache.WaitForCacheSync(ctx.Done(),\n\t\tc.ingressSynced,\n\t\tc.classSynced,\n\t\tc.serviceSynced,\n\t\tc.secretSynced,\n\t\tc.httpRouteSynced,\n\t\tc.gatewaySynced, // Wait for Gateway cache\n\t) {\n\t\treturn fmt.Errorf(\"failed to wait for caches to sync\")\n\t}\n\n\t_, err := c.classLister.Get(IngressClassName)\n\tif err == nil {\n\t\tlogger.Info(\"IngressClass already exists\")\n\t\treturn nil\n\t}\n\tif !errors.IsNotFound(err) {\n\t\treturn fmt.Errorf(\"failed to get IngressClass '%s': %v\", IngressClassName, err)\n\t}\n\n\tlogger.Info(\"IngressClass not found, creating...\")\n\tingressClass := &networkingv1.IngressClass{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: IngressClassName,\n\t\t},\n\t\tSpec: networkingv1.IngressClassSpec{\n\t\t\tController: IngressClassController,\n\t\t},\n\t}\n\tif config.DefaultConfig.IngressDefault {\n\t\tingressClass.Annotations = map[string]string{\n\t\t\tnetworkingv1.AnnotationIsDefaultIngressClass: \"true\",\n\t\t}\n\t}\n\t_, createErr := c.clientset.NetworkingV1().IngressClasses().Create(ctx, ingressClass, metav1.CreateOptions{})\n\treturn createErr\n}\n\n// Run will set up the event handlers for types we are interested in, as well\n// as start processing components for the specified number of workers.\nfunc (c *Controller) Run(ctx context.Context, workers int) {\n\tlogger := klog.FromContext(ctx).WithName(\"ingress\")\n\tctx = klog.NewContext(ctx, logger)\n\n\tdefer runtime.HandleCrash()\n\tdefer c.workqueue.ShutDown()\n\n\tlogger.Info(\"Starting Ingress controller\")\n\n\tlogger.Info(\"Starting workers\")\n\tfor i := 0; i < workers; i++ {\n\t\tgo wait.UntilWithContext(ctx, c.runWorker, time.Second)\n\t}\n\n\tlogger.Info(\"Started workers\")\n\t<-ctx.Done()\n\tlogger.Info(\"Shutting down workers\")\n}\n\nfunc (c *Controller) runWorker(ctx context.Context) {\n\tfor c.processNextWorkItem(ctx) {\n\t}\n}\n\nfunc (c *Controller) processNextWorkItem(ctx context.Context) bool {\n\tkey, shutdown := c.workqueue.Get()\n\tif shutdown {\n\t\treturn false\n\t}\n\n\terr := func() error {\n\t\tdefer c.workqueue.Done(key)\n\t\t// Run the syncHandler\n\t\tif err := c.syncHandler(ctx, key); err != nil {\n\t\t\t// Requeue on error\n\t\t\tc.workqueue.AddRateLimited(key)\n\t\t\treturn fmt.Errorf(\"error syncing '%s': %s, requeueing\", key, err.Error())\n\t\t}\n\t\tc.workqueue.Forget(key)\n\t\treturn nil\n\t}()\n\n\tif err != nil {\n\t\truntime.HandleError(err)\n\t}\n\n\treturn true\n}\n\n// syncHandler compares the actual state with the desired, and attempts to\n// converge the two.\nfunc (c *Controller) syncHandler(ctx context.Context, key string) error {\n\tnamespace, name, err := cache.SplitMetaNamespaceKey(key)\n\tif err != nil {\n\t\truntime.HandleError(fmt.Errorf(\"invalid resource key: %s\", key))\n\t\treturn nil\n\t}\n\tlogger := klog.FromContext(ctx).WithValues(\"ingress\", klog.KRef(namespace, name))\n\n\t// Get the Ingress resource\n\tingress, err := c.ingressLister.Ingresses(namespace).Get(name)\n\tif err != nil {\n\t\tif errors.IsNotFound(err) {\n\t\t\t// Kubernetes Garbage Collection will delete child HTTPRoutes due to OwnerReference.\n\t\t\t// We only need to reconcile the Gateway in case this Ingress\n\t\t\t// was the last one providing a particular TLS secret.\n\t\t\tlogger.V(4).Info(\"Ingress deleted. Reconciling Gateway.\")\n\t\t\tif _, err := c.reconcileNamespaceGateway(ctx, namespace); err != nil {\n\t\t\t\t// We still return an error to requeue, as Gateway reconciliation\n\t\t\t\t// might fail temporarily (e.g., API server issues).\n\t\t\t\treturn fmt.Errorf(\"failed to reconcile Gateway after Ingress deletion: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\t// Check if this Ingress is for us\n\tif !c.isIngressForUs(ingress) {\n\t\tlogger.V(4).Info(\"Skipping Ingress: not for this controller\")\n\t\t// TODO: If we *used* to own it, we should delete the HTTPRoutes\n\t\t// and reconcile the Gateway. For now, we assume GC handles routes.\n\t\treturn nil\n\t}\n\n\t// === 1. Ensure Namespace Gateway Exists & is Up-to-Date ===\n\t// This reconciles TLS secrets from ALL Ingresses in the namespace.\n\tgateway, err := c.reconcileNamespaceGateway(ctx, namespace)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to reconcile Gateway %s/%s: %w\", namespace, GatewayName, err)\n\t}\n\n\t// === 2. Reconcile HTTPRoutes (1-to-Many) ===\n\tlogger.V(4).Info(\"Reconciling HTTPRoutes for Ingress\")\n\n\t// Generate the desired state\n\tdesiredRoutes, err := c.generateDesiredHTTPRoutes(ingress, gateway.Name, gateway.Namespace)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to generate desired HTTPRoutes: %w\", err)\n\t}\n\n\t// Get the actual state\n\tallRoutes, err := c.httpRouteLister.HTTPRoutes(namespace).List(labels.Everything())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to list existing HTTPRoutes: %w\", err)\n\t}\n\n\texistingRoutes := make(map[string]*gatewayv1.HTTPRoute)\n\tfor _, route := range allRoutes {\n\t\tif metav1.IsControlledBy(route, ingress) {\n\t\t\texistingRoutes[route.Name] = route\n\t\t}\n\t}\n\n\t// Reconcile: Create/Update\n\tfor routeName, desiredRoute := range desiredRoutes {\n\t\tlogger = logger.WithValues(\"httpRoute\", klog.KRef(desiredRoute.Namespace, desiredRoute.Name))\n\t\texistingRoute, exists := existingRoutes[routeName]\n\t\tif !exists {\n\t\t\t// Create\n\t\t\tlogger.V(2).Info(\"Creating HTTPRoute\")\n\t\t\t_, createErr := c.gwClientset.GatewayV1().HTTPRoutes(namespace).Create(ctx, desiredRoute, metav1.CreateOptions{})\n\t\t\tif createErr != nil {\n\t\t\t\tlogger.Error(createErr, \"Failed to create HTTPRoute\")\n\t\t\t\treturn fmt.Errorf(\"failed to create HTTPRoute: %w\", createErr)\n\t\t\t}\n\t\t} else if !reflect.DeepEqual(existingRoute.Spec, desiredRoute.Spec) ||\n\t\t\t!reflect.DeepEqual(existingRoute.OwnerReferences, desiredRoute.OwnerReferences) {\n\n\t\t\tlogger.V(2).Info(\"Updating HTTPRoute\")\n\t\t\trouteCopy := existingRoute.DeepCopy()\n\t\t\trouteCopy.Spec = desiredRoute.Spec\n\t\t\trouteCopy.OwnerReferences = desiredRoute.OwnerReferences\n\n\t\t\t_, updateErr := c.gwClientset.GatewayV1().HTTPRoutes(namespace).Update(ctx, routeCopy, metav1.UpdateOptions{})\n\t\t\tif updateErr != nil {\n\t\t\t\tlogger.Error(updateErr, \"Failed to update HTTPRoute\")\n\t\t\t\treturn fmt.Errorf(\"failed to update HTTPRoute: %w\", updateErr)\n\t\t\t}\n\t\t}\n\t\t// Remove from map so we can find stale routes\n\t\tdelete(existingRoutes, routeName)\n\t}\n\n\t// Reconcile: Delete (stale routes)\n\tfor routeName, routeToDelete := range existingRoutes {\n\t\tlogger = logger.WithValues(\"httpRoute\", klog.KRef(routeToDelete.Namespace, routeName))\n\t\tlogger.V(2).Info(\"Deleting stale HTTPRoute\")\n\t\tdeleteErr := c.gwClientset.GatewayV1().HTTPRoutes(namespace).Delete(ctx, routeName, metav1.DeleteOptions{})\n\t\tif deleteErr != nil && !errors.IsNotFound(deleteErr) {\n\t\t\tlogger.Error(deleteErr, \"Failed to delete stale HTTPRoute\")\n\t\t\treturn fmt.Errorf(\"failed to delete stale HTTPRoute: %w\", deleteErr)\n\t\t}\n\t}\n\n\t// === 3. Update Ingress Status ===\n\t// We use the Gateway object we found/created. Its status might be stale\n\t// from the lister if it was just created. We grab the latest.\n\tlatestGateway, err := c.gwClientset.GatewayV1().Gateways(gateway.Namespace).Get(ctx, gateway.Name, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get latest Gateway %s/%s for status update: %w\", gateway.Namespace, gateway.Name, err)\n\t}\n\n\treturn c.updateIngressStatus(ctx, ingress, latestGateway)\n}\n\n// reconcileNamespaceGateway ensures the namespace Gateway exists and\n// its TLS configuration is in sync with ALL Ingresses in the namespace.\nfunc (c *Controller) reconcileNamespaceGateway(ctx context.Context, namespace string) (*gatewayv1.Gateway, error) {\n\t// 1. Aggregate all unique secret names from all Ingresses in this namespace\n\tingresses, err := c.ingressLister.Ingresses(namespace).List(labels.Everything())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list Ingresses in namespace %s: %w\", namespace, err)\n\t}\n\n\tsecretNames := make(map[string]struct{})\n\tfor _, ing := range ingresses {\n\t\tif !c.isIngressForUs(ing) {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, tls := range ing.Spec.TLS {\n\t\t\tif tls.SecretName != \"\" {\n\t\t\t\tsecretNames[tls.SecretName] = struct{}{}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Build the list of SecretObjectReferences\n\tcertRefs := []gatewayv1.SecretObjectReference{}\n\tfor secretName := range secretNames {\n\t\tcertRefs = append(certRefs, gatewayv1.SecretObjectReference{\n\t\t\tName: gatewayv1.ObjectName(secretName),\n\t\t})\n\t}\n\t// Sort the slice to prevent flapping updates\n\tsort.Slice(certRefs, func(i, j int) bool {\n\t\treturn certRefs[i].Name < certRefs[j].Name\n\t})\n\n\tdesiredListeners := []gatewayv1.Listener{\n\t\t{\n\t\t\tName:     \"http\",\n\t\t\tPort:     80,\n\t\t\tProtocol: gatewayv1.HTTPProtocolType,\n\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{\n\t\t\t\t\tFrom: ptr.To(gatewayv1.NamespacesFromSame), // Only allow HTTPRoutes from the same namespace\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// 3. Define the desired listeners\n\ttlsMode := gatewayv1.TLSModeTerminate // always use Terminate for Ingress TLS\n\tvar finalCertRefs []gatewayv1.SecretObjectReference\n\tif len(certRefs) > 0 {\n\t\tfinalCertRefs = certRefs\n\t\tdesiredListeners = append(desiredListeners, gatewayv1.Listener{\n\t\t\tName:     \"https\",\n\t\t\tPort:     443,\n\t\t\tProtocol: gatewayv1.HTTPSProtocolType,\n\t\t\tAllowedRoutes: &gatewayv1.AllowedRoutes{\n\t\t\t\tNamespaces: &gatewayv1.RouteNamespaces{\n\t\t\t\t\tFrom: ptr.To(gatewayv1.NamespacesFromSame), // Only allow HTTPRoutes from the same namespace\n\t\t\t\t},\n\t\t\t},\n\t\t\tTLS: &gatewayv1.ListenerTLSConfig{\n\t\t\t\tMode:            &tlsMode,\n\t\t\t\tCertificateRefs: finalCertRefs, // Set the aggregated certs\n\t\t\t},\n\t\t})\n\t}\n\n\tlogger := klog.FromContext(ctx).WithValues(\n\t\t\"gateway\", klog.KRef(namespace, GatewayName),\n\t\t\"gatewayClass\", c.gatewayClassName,\n\t)\n\n\t// 4. Get or Create the Gateway\n\tgw, err := c.gatewayLister.Gateways(namespace).Get(GatewayName)\n\tif err != nil {\n\t\tif !errors.IsNotFound(err) {\n\t\t\treturn nil, fmt.Errorf(\"failed to get Gateway %s/%s: %w\", namespace, GatewayName, err)\n\t\t}\n\n\t\t// Not found, create it\n\t\tlogger.V(2).Info(\"Creating Gateway for class\")\n\t\tnewGw := &gatewayv1.Gateway{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName:      GatewayName,\n\t\t\t\tNamespace: namespace,\n\t\t\t},\n\t\t\tSpec: gatewayv1.GatewaySpec{\n\t\t\t\tGatewayClassName: gatewayv1.ObjectName(c.gatewayClassName),\n\t\t\t\tListeners:        desiredListeners,\n\t\t\t},\n\t\t}\n\t\treturn c.gwClientset.GatewayV1().Gateways(namespace).Create(ctx, newGw, metav1.CreateOptions{})\n\t}\n\n\t// 5. Gateway exists, check if update is needed\n\tif !reflect.DeepEqual(gw.Spec.Listeners, desiredListeners) {\n\t\tlogger.V(2).Info(\"Updating Gateway with new listener configuration\")\n\t\t// This avoids conflicts with the gateway-controller updating status.\n\t\tpatch := map[string]interface{}{\n\t\t\t\"spec\": map[string]interface{}{\n\t\t\t\t\"listeners\": desiredListeners,\n\t\t\t},\n\t\t}\n\t\tpatchBytes, err := json.Marshal(patch)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to marshal patch for Gateway %s/%s: %w\", namespace, GatewayName, err)\n\t\t}\n\n\t\treturn c.gwClientset.GatewayV1().Gateways(namespace).Patch(ctx, gw.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{})\n\t}\n\n\t// No update needed\n\treturn gw, nil\n}\n\n// generateRouteName creates a stable, DNS-1123 compliant name for an HTTPRoute\n// based on its parent Ingress and the host rule.\nfunc generateRouteName(ingressName, host string) string {\n\tif host == \"\" {\n\t\t// This is for the default backend\n\t\treturn fmt.Sprintf(\"%s-default-backend\", ingressName)\n\t}\n\t// Use a hash of the host to ensure stability and DNS-1123 compliance\n\thash := sha256.Sum256([]byte(host))\n\t// Truncate hash to 10 chars for brevity\n\treturn fmt.Sprintf(\"%s-%s\", ingressName, hex.EncodeToString(hash[:])[:10])\n}\n\n// resolveBackendPort resolves the port number for a given Ingress service backend\nfunc (c *Controller) resolveBackendPort(ns string, svcBackend *networkingv1.IngressServiceBackend) (int32, error) {\n\tswitch svcPort := svcBackend.Port; {\n\tcase svcPort.Number != 0:\n\t\treturn svcPort.Number, nil\n\tcase svcPort.Name != \"\":\n\t\t// We need to look up the port number from the Service\n\t\tsvc, err := c.serviceLister.Services(ns).Get(svcBackend.Name)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"failed to get service %s/%s for port name %s: %w\",\n\t\t\t\tns, svcBackend.Name, svcPort.Name, err)\n\t\t}\n\t\t// Find the port\n\t\tfor _, port := range svc.Spec.Ports {\n\t\t\tif port.Name == svcPort.Name {\n\t\t\t\treturn port.Port, nil\n\t\t\t}\n\t\t}\n\t\treturn 0, fmt.Errorf(\"port name %s not found in service %s/%s\",\n\t\t\tsvcPort.Name, ns, svcBackend.Name)\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"backend service %s has no port defined\", svcBackend.Name)\n\t}\n}\n\n// translateIngressPaths translates Ingress paths to HTTPRouteRules,\n// ensuring Ingress precedence (Exact > Prefix, Longest > Shortest).\nfunc (c *Controller) translateIngressPaths(ns string, paths []networkingv1.HTTPIngressPath) ([]gatewayv1.HTTPRouteRule, error) {\n\tvar rules []gatewayv1.HTTPRouteRule\n\n\t// Create a copy to sort\n\tpathCopy := make([]networkingv1.HTTPIngressPath, len(paths))\n\tcopy(pathCopy, paths)\n\n\t// Sort paths to respect Ingress precedence\n\tsort.Slice(pathCopy, func(i, j int) bool {\n\t\tpathI := pathCopy[i]\n\t\tpathJ := pathCopy[j]\n\n\t\ttypeI := ptr.Deref(pathI.PathType, networkingv1.PathTypePrefix)\n\t\ttypeJ := ptr.Deref(pathJ.PathType, networkingv1.PathTypePrefix)\n\n\t\t// 1. Exact comes before Prefix\n\t\tif typeI == networkingv1.PathTypeExact && typeJ != networkingv1.PathTypeExact {\n\t\t\treturn true\n\t\t}\n\t\tif typeI != networkingv1.PathTypeExact && typeJ == networkingv1.PathTypeExact {\n\t\t\treturn false\n\t\t}\n\n\t\t// 2. If both are same type, longest path wins\n\t\treturn len(pathI.Path) > len(pathJ.Path)\n\t})\n\n\tfor _, ingressPath := range pathCopy {\n\t\t// Determine Path Match Type\n\t\tvar pathMatch gatewayv1.HTTPPathMatch\n\t\tpathType := ptr.Deref(ingressPath.PathType, networkingv1.PathTypePrefix)\n\n\t\tswitch pathType {\n\t\tcase networkingv1.PathTypePrefix:\n\t\t\tpathMatch.Type = ptr.To(gatewayv1.PathMatchPathPrefix)\n\t\t\tpathMatch.Value = &ingressPath.Path\n\t\tcase networkingv1.PathTypeExact:\n\t\t\tpathMatch.Type = ptr.To(gatewayv1.PathMatchExact)\n\t\t\tpathMatch.Value = &ingressPath.Path\n\t\tcase networkingv1.PathTypeImplementationSpecific:\n\t\t\t// Fallback (e.g., ImplementationSpecific)\n\t\t\tpathMatch.Type = ptr.To(gatewayv1.PathMatchPathPrefix)\n\t\t\tpathMatch.Value = &ingressPath.Path\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported path type: %s\", pathType)\n\t\t}\n\n\t\t// Determine Backend Port\n\t\tport, err := c.resolveBackendPort(ns, ingressPath.Backend.Service)\n\t\tif err != nil {\n\t\t\t// This error will cause the Ingress to be requeued\n\t\t\treturn nil, fmt.Errorf(\"error resolving port for path %s: %w\", ingressPath.Path, err)\n\t\t}\n\t\tportPtr := port // Take address of a copy\n\n\t\t// Create BackendRef\n\t\tbackendRef := gatewayv1.HTTPBackendRef{\n\t\t\tBackendRef: gatewayv1.BackendRef{\n\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\tName:  gatewayv1.ObjectName(ingressPath.Backend.Service.Name),\n\t\t\t\t\tKind:  ptr.To(gatewayv1.Kind(\"Service\")),\n\t\t\t\t\tGroup: ptr.To(gatewayv1.Group(\"\")),\n\t\t\t\t\tPort:  &portPtr,\n\t\t\t\t},\n\t\t\t\tWeight: ptr.To(int32(1)),\n\t\t\t},\n\t\t}\n\n\t\t// Create HTTPRouteRule\n\t\thttpRule := gatewayv1.HTTPRouteRule{\n\t\t\tMatches: []gatewayv1.HTTPRouteMatch{\n\t\t\t\t{\n\t\t\t\t\tPath: &pathMatch,\n\t\t\t\t},\n\t\t\t},\n\t\t\tBackendRefs: []gatewayv1.HTTPBackendRef{backendRef},\n\t\t}\n\t\trules = append(rules, httpRule)\n\t}\n\n\treturn rules, nil\n}\n\n// generateDesiredHTTPRoutes generates a map of all HTTPRoutes that should\n// exist for a given Ingress.\nfunc (c *Controller) generateDesiredHTTPRoutes(ingress *networkingv1.Ingress, gatewayName string, gatewayNamespace string) (map[string]*gatewayv1.HTTPRoute, error) {\n\tdesiredRoutes := make(map[string]*gatewayv1.HTTPRoute)\n\n\t// Set OwnerReference\n\townerRef := metav1.NewControllerRef(ingress, networkingv1.SchemeGroupVersion.WithKind(\"Ingress\"))\n\n\t// Base ParentReference\n\tparentRef := gatewayv1.ParentReference{\n\t\tName:      gatewayv1.ObjectName(gatewayName),\n\t\tNamespace: ptr.To(gatewayv1.Namespace(gatewayNamespace)),\n\t\tKind:      ptr.To(gatewayv1.Kind(\"Gateway\")),\n\t\tGroup:     ptr.To(gatewayv1.Group(gatewayv1.GroupName)),\n\t}\n\n\tvar defaultPaths []networkingv1.HTTPIngressPath\n\tvar hasDefaultRule bool\n\n\t// 1. Separate per-host rules from default (host: \"\") rules\n\tfor _, ingressRule := range ingress.Spec.Rules {\n\t\tif ingressRule.Host == \"\" {\n\t\t\t// This is a default rule. Collect its paths.\n\t\t\tif ingressRule.HTTP != nil {\n\t\t\t\tdefaultPaths = append(defaultPaths, ingressRule.HTTP.Paths...)\n\t\t\t\thasDefaultRule = true\n\t\t\t}\n\t\t\tcontinue // Skip per-host route creation\n\t\t}\n\n\t\tif ingressRule.HTTP == nil {\n\t\t\tcontinue\n\t\t}\n\t\trouteName := generateRouteName(ingress.Name, ingressRule.Host)\n\t\thostnames := []gatewayv1.Hostname{gatewayv1.Hostname(ingressRule.Host)}\n\n\t\t// Translate paths for this rule\n\t\trules, err := c.translateIngressPaths(ingress.Namespace, ingressRule.HTTP.Paths)\n\t\tif err != nil {\n\t\t\t// Propagate error (e.g., service port not found)\n\t\t\treturn nil, fmt.Errorf(\"failed to translate paths for host %s: %w\", ingressRule.Host, err)\n\t\t}\n\n\t\t// Construct the per-host HTTPRoute\n\t\thttpRoute := &gatewayv1.HTTPRoute{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName:            routeName,\n\t\t\t\tNamespace:       ingress.Namespace,\n\t\t\t\tOwnerReferences: []metav1.OwnerReference{*ownerRef},\n\t\t\t},\n\t\t\tSpec: gatewayv1.HTTPRouteSpec{\n\t\t\t\tCommonRouteSpec: gatewayv1.CommonRouteSpec{\n\t\t\t\t\tParentRefs: []gatewayv1.ParentReference{parentRef},\n\t\t\t\t},\n\t\t\t\tHostnames: hostnames, // This is correct, as host is not empty\n\t\t\t\tRules:     rules,\n\t\t\t},\n\t\t}\n\t\tdesiredRoutes[routeName] = httpRoute\n\t}\n\n\t// 2. Handle DefaultBackend (either from explicit rule or spec.defaultBackend)\n\tvar defaultRules []gatewayv1.HTTPRouteRule\n\tvar err error\n\n\tif hasDefaultRule { //nolint:gocritic\n\t\t// Case 1: A rule with host: \"\" exists. This takes precedence.\n\t\tdefaultRules, err = c.translateIngressPaths(ingress.Namespace, defaultPaths)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to translate paths for default rule: %w\", err)\n\t\t}\n\t} else if ingress.Spec.DefaultBackend != nil {\n\t\t// Case 2: No host: \"\" rule, but spec.defaultBackend exists.\n\t\tport, err := c.resolveBackendPort(ingress.Namespace, ingress.Spec.DefaultBackend.Service)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to resolve port for default backend: %w\", err)\n\t\t}\n\t\tportPtr := port // Take address of a copy\n\n\t\tdefaultRules = []gatewayv1.HTTPRouteRule{\n\t\t\t{\n\t\t\t\t// No matches means it's the default\n\t\t\t\tBackendRefs: []gatewayv1.HTTPBackendRef{\n\t\t\t\t\t{\n\t\t\t\t\t\tBackendRef: gatewayv1.BackendRef{\n\t\t\t\t\t\t\tBackendObjectReference: gatewayv1.BackendObjectReference{\n\t\t\t\t\t\t\t\tName:  gatewayv1.ObjectName(ingress.Spec.DefaultBackend.Service.Name),\n\t\t\t\t\t\t\t\tKind:  ptr.To(gatewayv1.Kind(\"Service\")),\n\t\t\t\t\t\t\t\tGroup: ptr.To(gatewayv1.Group(\"\")),\n\t\t\t\t\t\t\t\tPort:  &portPtr,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tWeight: ptr.To(int32(1)),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t} else {\n\t\t// Case 3: No default backend rules and no spec.defaultBackend.\n\t\t// We are done.\n\t\treturn desiredRoutes, nil\n\t}\n\n\t// 3. Create the single default HTTPRoute\n\trouteName := generateRouteName(ingress.Name, \"\") // Name is the same for both default cases\n\thttpRoute := &gatewayv1.HTTPRoute{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:            routeName,\n\t\t\tNamespace:       ingress.Namespace,\n\t\t\tOwnerReferences: []metav1.OwnerReference{*ownerRef},\n\t\t},\n\t\tSpec: gatewayv1.HTTPRouteSpec{\n\t\t\tCommonRouteSpec: gatewayv1.CommonRouteSpec{\n\t\t\t\tParentRefs: []gatewayv1.ParentReference{parentRef},\n\t\t\t},\n\t\t\t// Hostnames field is OMITTED (nil), which correctly\n\t\t\t// tells the Gateway to match all hosts.\n\t\t\tRules: defaultRules,\n\t\t},\n\t}\n\tdesiredRoutes[routeName] = httpRoute\n\n\treturn desiredRoutes, nil\n}\n\n// updateIngressStatus updates the Ingress status with the Gateway's IP\nfunc (c *Controller) updateIngressStatus(ctx context.Context, ingress *networkingv1.Ingress, gateway *gatewayv1.Gateway) error {\n\tlogger := klog.FromContext(ctx).WithValues(\"ingress\", klog.KObj(ingress))\n\n\t// Get the *latest* version of the Ingress to avoid update conflicts\n\tlatestIngress, err := c.clientset.NetworkingV1().Ingresses(ingress.Namespace).Get(ctx, ingress.Name, metav1.GetOptions{})\n\tif err != nil {\n\t\tif errors.IsNotFound(err) {\n\t\t\t// Ingress was deleted, nothing to update\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"failed to get latest Ingress %s/%s: %w\", ingress.Namespace, ingress.Name, err)\n\t}\n\n\t// Find an IP address in the Gateway status\n\tips := []string{}\n\thostnames := []string{}\n\tfor _, addr := range gateway.Status.Addresses {\n\t\tif addr.Type != nil && *addr.Type == gatewayv1.HostnameAddressType {\n\t\t\thostnames = append(hostnames, addr.Value)\n\t\t}\n\t\tif addr.Type != nil && (*addr.Type == gatewayv1.IPAddressType) {\n\t\t\tips = append(ips, addr.Value)\n\t\t}\n\t}\n\n\tif len(ips) == 0 && len(hostnames) == 0 {\n\t\t// No IP address found yet. The Gateway controller hasn't finished.\n\t\t// Return an error to trigger a rate-limited requeue.\n\t\treturn fmt.Errorf(\"gateway %s/%s has no IP or Hostname address in status yet\", gateway.Namespace, gateway.Name)\n\t}\n\n\t// Construct the new status\n\tlbStatus := &networkingv1.IngressLoadBalancerStatus{}\n\tfor _, ip := range ips {\n\t\tlbStatus.Ingress = append(lbStatus.Ingress, networkingv1.IngressLoadBalancerIngress{IP: ip})\n\t}\n\tfor _, hostname := range hostnames {\n\t\tlbStatus.Ingress = append(lbStatus.Ingress, networkingv1.IngressLoadBalancerIngress{Hostname: hostname})\n\t}\n\n\t// Check if status is already up-to-date\n\tif reflect.DeepEqual(latestIngress.Status.LoadBalancer, *lbStatus) {\n\t\tlogger.V(4).Info(\"Ingress status already up to date.\")\n\t\treturn nil\n\t}\n\n\tingressCopy := latestIngress.DeepCopy()\n\tingressCopy.Status.LoadBalancer = *lbStatus\n\n\t_, err = c.clientset.NetworkingV1().Ingresses(ingress.Namespace).UpdateStatus(ctx, ingressCopy, metav1.UpdateOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to update ingress status: %w\", err)\n\t}\n\tlogger.V(2).Info(\"Successfully updated status for Ingress\", \"IPs\", ips, \"hostNames\", hostnames)\n\treturn nil\n}\n\n// enqueueIngress takes an Ingress resource and converts it into a\n// namespace/name string which is then put onto the work queue.\nfunc (c *Controller) enqueueIngress(obj interface{}) {\n\tvar key string\n\tvar err error\n\tif key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {\n\t\truntime.HandleError(err)\n\t\treturn\n\t}\n\tklog.V(4).Infof(\"Enqueuing Ingress %s\", key)\n\tc.workqueue.Add(key)\n}\n\n// enqueueIngressFromRoute finds the owning Ingress for an HTTPRoute and enqueues it\nfunc (c *Controller) enqueueIngressFromRoute(obj interface{}) {\n\troute, ok := obj.(*gatewayv1.HTTPRoute)\n\tif !ok {\n\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\t\tif !ok {\n\t\t\truntime.HandleError(fmt.Errorf(\"error decoding object, invalid type\"))\n\t\t\treturn\n\t\t}\n\t\troute, ok = tombstone.Obj.(*gatewayv1.HTTPRoute)\n\t\tif !ok {\n\t\t\truntime.HandleError(fmt.Errorf(\"error decoding object tombstone, invalid type\"))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Find the Ingress owner\n\townerRef := metav1.GetControllerOf(route)\n\tif ownerRef == nil {\n\t\treturn\n\t}\n\n\t// Check if the owner is an Ingress\n\tif ownerRef.APIVersion == networkingv1.SchemeGroupVersion.String() && ownerRef.Kind == \"Ingress\" {\n\t\t// Enqueue the Ingress\n\t\tkey := route.Namespace + \"/\" + ownerRef.Name\n\t\tklog.V(4).Infof(\"Enqueuing Ingress %s due to change in HTTPRoute %s\", key, route.Name)\n\t\tc.workqueue.Add(key)\n\t}\n}\n\n// handleIngressClass checks if we are the default class\nfunc (c *Controller) handleIngressClass(obj interface{}) {\n\tclass, ok := obj.(*networkingv1.IngressClass)\n\tif !ok {\n\t\treturn\n\t}\n\n\tif class.Name != IngressClassName {\n\t\treturn\n\t}\n\t// Check if this is the default class\n\tisDefault := false\n\tval, ok := class.Annotations[networkingv1.AnnotationIsDefaultIngressClass]\n\tif ok && val == \"true\" {\n\t\tisDefault = true\n\t}\n\tif config.DefaultConfig.IngressDefault && !isDefault {\n\t\tklog.Infof(\"'%s' is now the default IngressClass\", IngressClassName)\n\t\t_, err := c.clientset.NetworkingV1().IngressClasses().Patch(context.TODO(), IngressClassName, types.MergePatchType, []byte(`{\"metadata\":{\"annotations\":{\"`+networkingv1.AnnotationIsDefaultIngressClass+`\":\"true\"}}}`), metav1.PatchOptions{})\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to patch IngressClass %s: %v\", IngressClassName, err)\n\t\t}\n\t\tisDefault = true\n\t}\n\tif isDefault != c.isDefaultClass.Load() {\n\t\t{\n\t\t\tif isDefault {\n\t\t\t\tklog.Infof(\"'%s' is now the default IngressClass\", IngressClassName)\n\t\t\t} else {\n\t\t\t\tklog.Infof(\"'%s' is no longer the default IngressClass\", IngressClassName)\n\t\t\t}\n\t\t\tc.isDefaultClass.Store(isDefault)\n\t\t\t// Re-enqueue all Ingresses that might be affected by this change\n\t\t\tc.enqueueAllIngresses()\n\t\t}\n\n\t}\n}\n\n// handleObject will take any resource implementing metav1.Object\n// and find any Ingress that references it, adding that Ingress to the\n// work queue.\nfunc (c *Controller) handleObject(obj interface{}) {\n\tvar object metav1.Object\n\tvar ok bool\n\tif object, ok = obj.(metav1.Object); !ok {\n\t\t// handle delete tombstones\n\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\t\tif !ok {\n\t\t\truntime.HandleError(fmt.Errorf(\"error decoding object, invalid type\"))\n\t\t\treturn\n\t\t}\n\t\tobject, ok = tombstone.Obj.(metav1.Object)\n\t\tif !ok {\n\t\t\truntime.HandleError(fmt.Errorf(\"error decoding object tombstone, invalid type\"))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// List all ingresses\n\tingresses, err := c.ingressLister.List(labels.Everything())\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to list Ingresses: %v\", err)\n\t\treturn\n\t}\n\n\tfor _, ingress := range ingresses {\n\t\tif !c.isIngressForUs(ingress) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check if this ingress references the object\n\t\tswitch obj.(type) {\n\t\tcase *corev1.Service:\n\t\t\tif c.ingressReferencesService(ingress, object.GetNamespace(), object.GetName()) {\n\t\t\t\tklog.V(4).Infof(\"Enqueuing Ingress %s/%s due to change in Service %s/%s\", ingress.Namespace, ingress.Name, object.GetNamespace(), object.GetName())\n\t\t\t\tc.enqueueIngress(ingress)\n\t\t\t}\n\t\tcase *corev1.Secret:\n\t\t\tif c.ingressReferencesSecret(ingress, object.GetNamespace(), object.GetName()) {\n\t\t\t\tklog.V(4).Infof(\"Enqueuing Ingress %s/%s due to change in Secret %s/%s\", ingress.Namespace, ingress.Name, object.GetNamespace(), object.GetName())\n\t\t\t\t// When a secret changes, we must re-enqueue ALL ingresses in that namespace\n\t\t\t\t// to re-calculate the Gateway's aggregated certificate list.\n\t\t\t\tc.enqueueAllIngressesInNamespace(object.GetNamespace())\n\t\t\t}\n\t\t}\n\t}\n}\n\n// handleGateway re-enqueues all Ingresses in a namespace when its Gateway changes\nfunc (c *Controller) handleGateway(obj interface{}) {\n\tgw, ok := obj.(*gatewayv1.Gateway)\n\tif !ok {\n\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\t\tif !ok {\n\t\t\truntime.HandleError(fmt.Errorf(\"error decoding object, invalid type\"))\n\t\t\treturn\n\t\t}\n\t\tgw, ok = tombstone.Obj.(*gatewayv1.Gateway)\n\t\tif !ok {\n\t\t\truntime.HandleError(fmt.Errorf(\"error decoding object tombstone, invalid type\"))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// If this is one of our managed Gateways, re-enqueue all Ingresses in that namespace\n\t// This is critical for updating Ingress status when the Gateway gets an IP\n\tif gw.Name == GatewayName {\n\t\tklog.V(4).Infof(\"Gateway %s/%s changed, re-enqueuing all Ingresses in namespace %s\", gw.Namespace, gw.Name, gw.Namespace)\n\t\tc.enqueueAllIngressesInNamespace(gw.Namespace)\n\t}\n}\n\n// enqueueAllIngressesInNamespace enqueues all Ingresses for a specific namespace\nfunc (c *Controller) enqueueAllIngressesInNamespace(namespace string) {\n\tingresses, err := c.ingressLister.Ingresses(namespace).List(labels.Everything())\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to list Ingresses in namespace %s: %v\", namespace, err)\n\t\treturn\n\t}\n\tfor _, ingress := range ingresses {\n\t\tc.enqueueIngress(ingress)\n\t}\n}\n\nfunc (c *Controller) ingressReferencesService(ingress *networkingv1.Ingress, ns, name string) bool {\n\tif ingress.Namespace != ns {\n\t\treturn false\n\t}\n\tif ingress.Spec.DefaultBackend != nil && ingress.Spec.DefaultBackend.Service.Name == name {\n\t\treturn true\n\t}\n\tfor _, rule := range ingress.Spec.Rules {\n\t\tif rule.HTTP == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, path := range rule.HTTP.Paths {\n\t\t\tif path.Backend.Service.Name == name {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Controller) ingressReferencesSecret(ingress *networkingv1.Ingress, ns, name string) bool {\n\tif ingress.Namespace != ns {\n\t\treturn false\n\t}\n\tfor _, tls := range ingress.Spec.TLS {\n\t\tif tls.SecretName == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// isIngressForUs checks if an Ingress belongs to this controller\nfunc (c *Controller) isIngressForUs(ingress *networkingv1.Ingress) bool {\n\t// Case 1: Ingress specifies IngressClassName\n\tif ingress.Spec.IngressClassName != nil {\n\t\treturn *ingress.Spec.IngressClassName == IngressClassName\n\t}\n\t// Case 2: No IngressClassName, check if we are default\n\treturn c.isDefaultClass.Load()\n}\n\nfunc (c *Controller) enqueueAllIngresses() {\n\tingresses, err := c.ingressLister.List(labels.Everything())\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to list all Ingresses: %v\", err)\n\t\treturn\n\t}\n\tklog.Info(\"Enqueuing all Ingresses due to IngressClass change\")\n\tfor _, ingress := range ingresses {\n\t\tc.enqueueIngress(ingress)\n\t}\n}\n"
  },
  {
    "path": "pkg/ingress/controller_test.go",
    "content": "package ingress\n\nimport (\n\t\"context\" // New import\n\t// New import\n\t\"fmt\"\n\t\"reflect\" // Import reflect for DeepEqual\n\t\"strings\" // Import standard library strings package\n\t\"testing\"\n\t\"time\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\t\"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\tkubeinformers \"k8s.io/client-go/informers\"\n\tfakekube \"k8s.io/client-go/kubernetes/fake\"\n\t\"k8s.io/client-go/tools/cache\"\n\t\"k8s.io/utils/ptr\" // Added for pointer helpers\n\n\tgatewayv1 \"sigs.k8s.io/gateway-api/apis/v1\"\n\tfakegateway \"sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/fake\"\n\tgatewayinformers \"sigs.k8s.io/gateway-api/pkg/client/informers/externalversions\"\n)\n\nconst (\n\ttestGatewayClassName = \"test-gw-class\"\n\ttestNamespace        = \"test-ns\"\n\ttestIngressName      = \"test-ingress\"\n\ttestServiceName      = \"test-service\"\n\ttestServicePortName  = \"http\"\n\ttestServicePortNum   = 8080\n)\n\n// testFixture holds all the components needed for a test\ntype testFixture struct {\n\tt           *testing.T\n\tctx         context.Context\n\tcancel      context.CancelFunc\n\tcontroller  *Controller\n\tkubeClient  *fakekube.Clientset\n\tgwClient    *fakegateway.Clientset\n\tkubeObjects []runtime.Object\n\tgwObjects   []runtime.Object\n}\n\n// newTestFixture creates a new test harness\nfunc newTestFixture(t *testing.T, kubeObjects []runtime.Object, gwObjects []runtime.Object) *testFixture {\n\tctx, cancel := context.WithCancel(context.Background())\n\tkubeClient := fakekube.NewSimpleClientset(kubeObjects...)\n\tgwClient := fakegateway.NewSimpleClientset(gwObjects...)\n\n\tkubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, 0)\n\tgwInformerFactory := gatewayinformers.NewSharedInformerFactory(gwClient, 0)\n\n\t// Get informers\n\tingInformer := kubeInformerFactory.Networking().V1().Ingresses()\n\tclassInformer := kubeInformerFactory.Networking().V1().IngressClasses()\n\tsvcInformer := kubeInformerFactory.Core().V1().Services()\n\tsecretInformer := kubeInformerFactory.Core().V1().Secrets()\n\trouteInformer := gwInformerFactory.Gateway().V1().HTTPRoutes()\n\tgwInformer := gwInformerFactory.Gateway().V1().Gateways()\n\n\t// Create controller\n\tcontroller, err := NewController(\n\t\tkubeClient,\n\t\tgwClient,\n\t\ttestGatewayClassName,\n\t\tingInformer,\n\t\tclassInformer,\n\t\tsvcInformer,\n\t\tsecretInformer,\n\t\trouteInformer,\n\t\tgwInformer,\n\t)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create controller: %v\", err)\n\t}\n\n\t// Start informers\n\tkubeInformerFactory.Start(ctx.Done())\n\tgwInformerFactory.Start(ctx.Done())\n\n\t// Wait for caches to sync\n\tok := cache.WaitForCacheSync(ctx.Done(),\n\t\tingInformer.Informer().HasSynced,\n\t\tclassInformer.Informer().HasSynced,\n\t\tsvcInformer.Informer().HasSynced,\n\t\tsecretInformer.Informer().HasSynced,\n\t\trouteInformer.Informer().HasSynced,\n\t\tgwInformer.Informer().HasSynced,\n\t)\n\tif !ok {\n\t\tt.Fatalf(\"Failed to sync caches\")\n\t}\n\n\treturn &testFixture{\n\t\tt:           t,\n\t\tctx:         ctx,\n\t\tcancel:      cancel,\n\t\tcontroller:  controller,\n\t\tkubeClient:  kubeClient,\n\t\tgwClient:    gwClient,\n\t\tkubeObjects: kubeObjects,\n\t\tgwObjects:   gwObjects,\n\t}\n}\n\n// --- Helper Objects ---\n\nfunc newTestIngressClass() *networkingv1.IngressClass {\n\treturn &networkingv1.IngressClass{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: IngressClassName,\n\t\t},\n\t\tSpec: networkingv1.IngressClassSpec{\n\t\t\tController: IngressClassController,\n\t\t},\n\t}\n}\n\nfunc newTestService(name string) *corev1.Service {\n\treturn &corev1.Service{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: testNamespace,\n\t\t},\n\t\tSpec: corev1.ServiceSpec{\n\t\t\tPorts: []corev1.ServicePort{\n\t\t\t\t{\n\t\t\t\t\tName: testServicePortName,\n\t\t\t\t\tPort: int32(testServicePortNum),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName: \"other-port\",\n\t\t\t\t\tPort: 8181,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc newTestIngress(name string) *networkingv1.Ingress {\n\tpathType := networkingv1.PathTypePrefix\n\treturn &networkingv1.Ingress{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: testNamespace,\n\t\t},\n\t\tSpec: networkingv1.IngressSpec{\n\t\t\tIngressClassName: ptr.To(IngressClassName),\n\t\t\tRules: []networkingv1.IngressRule{\n\t\t\t\t{\n\t\t\t\t\tHost: \"example.com\",\n\t\t\t\t\tIngressRuleValue: networkingv1.IngressRuleValue{\n\t\t\t\t\t\tHTTP: &networkingv1.HTTPIngressRuleValue{\n\t\t\t\t\t\t\tPaths: []networkingv1.HTTPIngressPath{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tPath:     \"/\",\n\t\t\t\t\t\t\t\t\tPathType: &pathType,\n\t\t\t\t\t\t\t\t\tBackend: networkingv1.IngressBackend{\n\t\t\t\t\t\t\t\t\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\t\t\t\t\t\t\t\t\tName: testServiceName,\n\t\t\t\t\t\t\t\t\t\t\tPort: networkingv1.ServiceBackendPort{\n\t\t\t\t\t\t\t\t\t\t\t\tName: testServicePortName, // Test port name translation\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\n// --- Test Cases ---\n\nfunc TestSyncHandler_Create(t *testing.T) {\n\t// 1. Setup\n\tingress := newTestIngress(testIngressName)\n\tservice := newTestService(testServiceName)\n\tingressClass := newTestIngressClass()\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingress, service, ingressClass}, // kube objects\n\t\t[]runtime.Object{}, // gateway objects\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. First Sync: Create Gateway, HTTPRoute. Fails on status update.\n\terr := f.controller.syncHandler(f.ctx, key)\n\tif err == nil {\n\t\tt.Fatalf(\"First sync should fail waiting for Gateway IP, but got nil error\")\n\t}\n\tif !strings.Contains(err.Error(), \"has no IP or Hostname address in status yet\") {\n\t\tt.Errorf(\"Error message should indicate missing IP, but got: %v\", err)\n\t}\n\n\t// 3. Assert Gateway was created\n\tgw, err := f.gwClient.GatewayV1().Gateways(testNamespace).Get(f.ctx, GatewayName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get created Gateway: %v\", err)\n\t}\n\tif string(gw.Spec.GatewayClassName) != testGatewayClassName {\n\t\tt.Errorf(\"Gateway Class: expected %q, got %q\", testGatewayClassName, gw.Spec.GatewayClassName)\n\t}\n\t// With no Ingress TLS, Gateway should only have 1 listener (http)\n\tif len(gw.Spec.Listeners) != 1 {\n\t\tt.Errorf(\"Gateway Listeners: expected %d, got %d\", 1, len(gw.Spec.Listeners))\n\t}\n\tif string(gw.Spec.Listeners[0].Name) != \"http\" {\n\t\tt.Errorf(\"Listener 0: expected %q, got %q\", \"http\", gw.Spec.Listeners[0].Name)\n\t}\n\n\t// 4. Assert HTTPRoute was created (with the new name)\n\texpectedRouteName := generateRouteName(testIngressName, \"example.com\")\n\troute, err := f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, expectedRouteName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get created HTTPRoute: %v\", err)\n\t}\n\tif route.Name != expectedRouteName {\n\t\tt.Errorf(\"HTTPRoute Name: expected %q, got %q\", expectedRouteName, route.Name)\n\t}\n\t// Check Hostname\n\tif len(route.Spec.Hostnames) != 1 || route.Spec.Hostnames[0] != \"example.com\" {\n\t\tt.Errorf(\"HTTPRoute Hostnames: expected [\\\"example.com\\\"], got %v\", route.Spec.Hostnames)\n\t}\n\t// Check ParentRef\n\tif len(route.Spec.ParentRefs) != 1 {\n\t\tt.Fatalf(\"HTTPRoute ParentRefs: expected %d, got %d\", 1, len(route.Spec.ParentRefs))\n\t}\n\tif string(route.Spec.ParentRefs[0].Name) != GatewayName {\n\t\tt.Errorf(\"ParentRef Name: expected %q, got %q\", GatewayName, route.Spec.ParentRefs[0].Name)\n\t}\n\tif route.Spec.ParentRefs[0].Namespace == nil || string(*route.Spec.ParentRefs[0].Namespace) != testNamespace {\n\t\tt.Errorf(\"ParentRef Namespace: expected %q, got %v\", testNamespace, route.Spec.ParentRefs[0].Namespace)\n\t}\n\t// Check BackendRef (port name was translated to number)\n\tif len(route.Spec.Rules) != 1 {\n\t\tt.Fatalf(\"HTTPRoute Rules: expected %d, got %d\", 1, len(route.Spec.Rules))\n\t}\n\tif len(route.Spec.Rules[0].BackendRefs) != 1 {\n\t\tt.Fatalf(\"HTTPRoute BackendRefs: expected %d, got %d\", 1, len(route.Spec.Rules[0].BackendRefs))\n\t}\n\tif route.Spec.Rules[0].BackendRefs[0].Port == nil || int32(*route.Spec.Rules[0].BackendRefs[0].Port) != int32(testServicePortNum) {\n\t\tt.Errorf(\"BackendRef Port: expected %d, got %v\", testServicePortNum, route.Spec.Rules[0].BackendRefs[0].Port)\n\t}\n\n\t// 5. Fake the Gateway Controller: Update Gateway status with a Hostname\n\tgw.Status.Addresses = []gatewayv1.GatewayStatusAddress{\n\t\t{\n\t\t\tType:  ptr.To(gatewayv1.HostnameAddressType),\n\t\t\tValue: \"my-test-lb.com\",\n\t\t},\n\t}\n\t_, err = f.gwClient.GatewayV1().Gateways(testNamespace).UpdateStatus(f.ctx, gw, metav1.UpdateOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to update Gateway status: %v\", err)\n\t}\n\n\t// 6. Second Sync: Update Ingress Status\n\t// We must use a poller here because the controller's informer needs to see the status update.\n\t// The handleGateway function will re-enqueue the Ingress.\n\terr = wait.PollUntilContextTimeout(f.ctx, 100*time.Millisecond, 5*time.Second, false, func(ctx context.Context) (bool, error) {\n\t\t// We call processNextWorkItem to simulate the worker picking up the key\n\t\t// that handleGateway enqueued.\n\t\tif f.controller.workqueue.Len() > 0 {\n\t\t\tf.controller.processNextWorkItem(ctx)\n\t\t}\n\n\t\t// Check if ingress status is updated\n\t\ting, err := f.kubeClient.NetworkingV1().Ingresses(testNamespace).Get(ctx, testIngressName, metav1.GetOptions{})\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tif ing.Status.LoadBalancer.Ingress != nil && len(ing.Status.LoadBalancer.Ingress) > 0 {\n\t\t\treturn ing.Status.LoadBalancer.Ingress[0].Hostname == \"my-test-lb.com\", nil\n\t\t}\n\t\treturn false, nil\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to update Ingress status with Gateway Hostname: %v\", err)\n\t}\n}\n\nfunc TestSyncHandler_Delete(t *testing.T) {\n\t// 1. Setup: Start with an existing Gateway with TLS\n\t// This test verifies that when an Ingress is deleted, the Gateway is\n\t// reconciled (e.g., to remove TLS certs).\n\t// HTTPRoute deletion is handled by GC, so we don't test that here.\n\n\t// This Gateway has an HTTPS listener that should be removed\n\texistingGateway := &gatewayv1.Gateway{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      GatewayName,\n\t\t\tNamespace: testNamespace,\n\t\t},\n\t\tSpec: gatewayv1.GatewaySpec{\n\t\t\tGatewayClassName: testGatewayClassName,\n\t\t\tListeners: []gatewayv1.Listener{\n\t\t\t\t{Name: \"http\", Port: 80, Protocol: gatewayv1.HTTPProtocolType},\n\t\t\t\t{ // This listener should be removed\n\t\t\t\t\tName:     \"https\",\n\t\t\t\t\tPort:     443,\n\t\t\t\t\tProtocol: gatewayv1.HTTPSProtocolType,\n\t\t\t\t\tTLS: &gatewayv1.ListenerTLSConfig{\n\t\t\t\t\t\tMode: ptr.To(gatewayv1.TLSModeTerminate),\n\t\t\t\t\t\tCertificateRefs: []gatewayv1.SecretObjectReference{\n\t\t\t\t\t\t\t{Name: \"old-secret\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tingressClass := newTestIngressClass()\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingressClass},    // kube objects\n\t\t[]runtime.Object{existingGateway}, // gateway objects\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. Sync: Ingress is not found, so controller should reconcile the Gateway\n\terr := f.controller.syncHandler(f.ctx, key)\n\tif err != nil {\n\t\tt.Fatalf(\"SyncHandler should not error on delete, but got: %v\", err)\n\t}\n\n\t// 3. Assert Gateway was updated to remove HTTPS listener\n\tgw, err := f.gwClient.GatewayV1().Gateways(testNamespace).Get(f.ctx, GatewayName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get Gateway: %v\", err)\n\t}\n\tif len(gw.Spec.Listeners) != 1 {\n\t\tt.Errorf(\"Gateway Listeners: expected 1 (http only), got %d\", len(gw.Spec.Listeners))\n\t}\n\tif gw.Spec.Listeners[0].Name != \"http\" {\n\t\tt.Errorf(\"Gateway listener should be http, got %s\", gw.Spec.Listeners[0].Name)\n\t}\n}\n\nfunc TestSyncHandler_TranslationError_ServicePort(t *testing.T) {\n\t// 1. Setup: Ingress references a port name that doesn't exist on the service\n\tingress := newTestIngress(testIngressName)\n\tservice := newTestService(testServiceName)\n\n\t// Modify ingress to point to a bad port name\n\tingress.Spec.Rules[0].HTTP.Paths[0].Backend.Service.Port.Name = \"bad-port-name\"\n\tingress.Spec.Rules[0].HTTP.Paths[0].Backend.Service.Port.Number = 0\n\n\tingressClass := newTestIngressClass()\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingress, service, ingressClass},\n\t\t[]runtime.Object{},\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. Sync: Translation should fail\n\terr := f.controller.syncHandler(f.ctx, key)\n\tif err == nil {\n\t\tt.Fatalf(\"SyncHandler should error on bad port name, but got nil error\")\n\t}\n\tif !strings.Contains(err.Error(), \"port name bad-port-name not found in service\") {\n\t\tt.Errorf(\"Error message should indicate missing port, but got: %v\", err)\n\t}\n\n\t// 3. Assert HTTPRoute was NOT created\n\texpectedRouteName := generateRouteName(testIngressName, \"example.com\")\n\t_, err = f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, expectedRouteName, metav1.GetOptions{})\n\tif !errors.IsNotFound(err) {\n\t\tt.Errorf(\"HTTPRoute should not be created (IsNotFound), but got: %v\", err)\n\t}\n}\nfunc TestSyncHandler_TLS_Aggregation(t *testing.T) {\n\t// 1. Setup\n\tservice := newTestService(testServiceName)\n\tingressClass := newTestIngressClass()\n\n\t// Ingress A specifies secret-a\n\tingressA := newTestIngress(\"ingress-a\")\n\tingressA.Spec.TLS = []networkingv1.IngressTLS{\n\t\t{SecretName: \"secret-a\"},\n\t}\n\n\t// Ingress B specifies secret-b and a duplicate secret-a\n\tingressB := newTestIngress(\"ingress-b\")\n\tingressB.Spec.Rules[0].Host = \"b.example.com\"\n\tingressB.Spec.TLS = []networkingv1.IngressTLS{\n\t\t{SecretName: \"secret-b\"},\n\t\t{SecretName: \"secret-a\"}, // Duplicate\n\t}\n\n\t// Ingress C is not managed by us\n\tingressC := newTestIngress(\"ingress-c\")\n\tingressC.Spec.Rules[0].Host = \"c.example.com\"\n\tingressC.Spec.IngressClassName = ptr.To(\"other-class\") // Different class\n\tingressC.Spec.TLS = []networkingv1.IngressTLS{\n\t\t{SecretName: \"secret-c\"},\n\t}\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{service, ingressClass, ingressA, ingressB, ingressC}, // kube objects\n\t\t[]runtime.Object{}, // gateway objects\n\t)\n\tdefer f.cancel()\n\n\tkeyA := fmt.Sprintf(\"%s/%s\", testNamespace, \"ingress-a\")\n\tkeyB := fmt.Sprintf(\"%s/%s\", testNamespace, \"ingress-b\")\n\n\t// 2. Sync Ingress A\n\t// This sync will fail on status update, but that's OK.\n\t// We only care about the Gateway reconciliation.\n\t// The controller's lister will see ALL ingresses in the namespace.\n\t_ = f.controller.syncHandler(f.ctx, keyA)\n\n\t// 3. Assert Gateway is created with secret-a AND secret-b\n\tgw, err := f.gwClient.GatewayV1().Gateways(testNamespace).Get(f.ctx, GatewayName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get created Gateway: %v\", err)\n\t}\n\n\t// Gateway should now have 2 listeners\n\tif len(gw.Spec.Listeners) != 2 {\n\t\tt.Fatalf(\"Gateway Listeners: expected 2, got %d\", len(gw.Spec.Listeners))\n\t}\n\thttpsListener := gw.Spec.Listeners[1]\n\tif httpsListener.Name != \"https\" {\n\t\tt.Fatal(\"Listener 1 is not 'https'\")\n\t}\n\tif httpsListener.TLS == nil || *httpsListener.TLS.Mode != gatewayv1.TLSModeTerminate {\n\t\tt.Errorf(\"TLS Mode: expected %q, got %v\", gatewayv1.TLSModeTerminate, httpsListener.TLS)\n\t}\n\n\t// Secrets are sorted: secret-a, secret-b. secret-c is ignored.\n\texpectedCerts := []gatewayv1.SecretObjectReference{\n\t\t{Name: \"secret-a\"},\n\t\t{Name: \"secret-b\"},\n\t}\n\tif !reflect.DeepEqual(httpsListener.TLS.CertificateRefs, expectedCerts) {\n\t\tt.Errorf(\"Gateway certs: expected %v, got %v\", expectedCerts, httpsListener.TLS.CertificateRefs)\n\t}\n\n\t// 4. Sync Ingress B\n\t// This sync should be a no-op for the Gateway, as state is already correct.\n\t_ = f.controller.syncHandler(f.ctx, keyB)\n\tgw, err = f.gwClient.GatewayV1().Gateways(testNamespace).Get(f.ctx, GatewayName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get updated Gateway: %v\", err)\n\t}\n\tif !reflect.DeepEqual(gw.Spec.Listeners[1].TLS.CertificateRefs, expectedCerts) {\n\t\tt.Errorf(\"Gateway certs should be unchanged, but they were: %v\", gw.Spec.Listeners[1].TLS.CertificateRefs)\n\t}\n\n\t// 5. Update Ingress A to remove its TLS spec\n\tingressAUpdate, err := f.kubeClient.NetworkingV1().Ingresses(testNamespace).Get(f.ctx, \"ingress-a\", metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get ingress-a for update: %v\", err)\n\t}\n\tingressAUpdate.Spec.TLS = nil\n\t_, err = f.kubeClient.NetworkingV1().Ingresses(testNamespace).Update(f.ctx, ingressAUpdate, metav1.UpdateOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to update ingress-a to remove TLS: %v\", err)\n\t}\n\n\t// Wait for the informer to see the update\n\ttime.Sleep(100 * time.Millisecond)\n\n\t// 6. Re-sync Ingress A (keyA)\n\t// This sync will now see only Ingress B has TLS.\n\t_ = f.controller.syncHandler(f.ctx, keyA)\n\n\t// 7. Assert Gateway is UPDATED, now only with secret-a and secret-b (from Ingress B)\n\tgw, err = f.gwClient.GatewayV1().Gateways(testNamespace).Get(f.ctx, GatewayName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get updated Gateway: %v\", err)\n\t}\n\n\t// Ingress B still holds both \"secret-a\" and \"secret-b\"\n\texpectedCerts = []gatewayv1.SecretObjectReference{\n\t\t{Name: \"secret-a\"},\n\t\t{Name: \"secret-b\"},\n\t}\n\tif len(gw.Spec.Listeners) != 2 { // Still 2 listeners, cert list is unchanged\n\t\tt.Errorf(\"Gateway listener count: expected 2, got %d\", len(gw.Spec.Listeners))\n\t}\n\tif !reflect.DeepEqual(gw.Spec.Listeners[1].TLS.CertificateRefs, expectedCerts) {\n\t\tt.Errorf(\"Gateway certs: expected %v, got %v\", expectedCerts, gw.Spec.Listeners[1].TLS.CertificateRefs)\n\t}\n\n\t// 8. Update Ingress B to remove its TLS\n\tingressBUpdate, err := f.kubeClient.NetworkingV1().Ingresses(testNamespace).Get(f.ctx, \"ingress-b\", metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get ingress-b for update: %v\", err)\n\t}\n\tingressBUpdate.Spec.TLS = nil\n\t_, err = f.kubeClient.NetworkingV1().Ingresses(testNamespace).Update(f.ctx, ingressBUpdate, metav1.UpdateOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to update ingress-b to remove TLS: %v\", err)\n\t}\n\n\t// Wait for the informer to see the update\n\ttime.Sleep(100 * time.Millisecond)\n\n\t// 9. Re-sync Ingress B (keyB)\n\t// This sync will now see *zero* ingresses with TLS.\n\t_ = f.controller.syncHandler(f.ctx, keyB)\n\n\t// 10. Assert Gateway is UPDATED again, now with *no* HTTPS listener\n\tgw, err = f.gwClient.GatewayV1().Gateways(testNamespace).Get(f.ctx, GatewayName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get updated Gateway: %v\", err)\n\t}\n\n\tif len(gw.Spec.Listeners) != 1 {\n\t\tt.Errorf(\"Gateway listener count: expected 1 (http only), got %d\", len(gw.Spec.Listeners))\n\t}\n\tif gw.Spec.Listeners[0].Name != \"http\" {\n\t\tt.Errorf(\"Gateway listener should be http, got %s\", gw.Spec.Listeners[0].Name)\n\t}\n}\n\n// === NEW TEST ===\nfunc TestSyncHandler_DefaultBackend(t *testing.T) {\n\t// 1. Setup: Ingress with ONLY spec.defaultBackend\n\tingress := newTestIngress(testIngressName)\n\tingress.Spec.Rules = nil // No rules\n\tingress.Spec.DefaultBackend = &networkingv1.IngressBackend{\n\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\tName: testServiceName,\n\t\t\tPort: networkingv1.ServiceBackendPort{Number: int32(testServicePortNum)},\n\t\t},\n\t}\n\n\tservice := newTestService(testServiceName)\n\tingressClass := newTestIngressClass()\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingress, service, ingressClass},\n\t\t[]runtime.Object{},\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. Sync\n\t// This will fail on status update, which is fine\n\t_ = f.controller.syncHandler(f.ctx, key)\n\n\t// 3. Assert HTTPRoute was created for the default backend\n\texpectedRouteName := generateRouteName(testIngressName, \"\") // \"\" host\n\troute, err := f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, expectedRouteName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get created HTTPRoute for default backend: %v\", err)\n\t}\n\n\t// 4. Assert Hostnames is nil (meaning \"all hosts\")\n\tif route.Spec.Hostnames != nil {\n\t\tt.Errorf(\"Default backend route should have nil Hostnames, got %v\", route.Spec.Hostnames)\n\t}\n\n\t// 5. Assert Rule is correct\n\tif len(route.Spec.Rules) != 1 {\n\t\tt.Fatalf(\"Default backend route Rules: expected 1, got %d\", len(route.Spec.Rules))\n\t}\n\tif route.Spec.Rules[0].Matches != nil {\n\t\tt.Errorf(\"Default backend rule Matches: expected nil, got %v\", route.Spec.Rules[0].Matches)\n\t}\n\tif len(route.Spec.Rules[0].BackendRefs) != 1 {\n\t\tt.Fatalf(\"Default backend rule BackendRefs: expected 1, got %d\", len(route.Spec.Rules[0].BackendRefs))\n\t}\n\tbackendRef := route.Spec.Rules[0].BackendRefs[0]\n\tif string(backendRef.Name) != testServiceName {\n\t\tt.Errorf(\"BackendRef Name: expected %s, got %s\", testServiceName, backendRef.Name)\n\t}\n\tif *backendRef.Port != int32(testServicePortNum) {\n\t\tt.Errorf(\"BackendRef Port: expected %d, got %d\", testServicePortNum, *backendRef.Port)\n\t}\n}\n\n// === NEW TEST ===\nfunc TestSyncHandler_DefaultRulePrecedence(t *testing.T) {\n\t// 1. Setup: Ingress with BOTH spec.defaultBackend and a host: \"\" rule.\n\t// The host: \"\" rule should win.\n\tserviceA := newTestService(\"service-a\")\n\tserviceB := newTestService(\"service-b\")\n\n\tingress := newTestIngress(testIngressName)\n\tingress.Spec.Rules = []networkingv1.IngressRule{\n\t\t{\n\t\t\tHost: \"\", // Default rule\n\t\t\tIngressRuleValue: networkingv1.IngressRuleValue{\n\t\t\t\tHTTP: &networkingv1.HTTPIngressRuleValue{\n\t\t\t\t\tPaths: []networkingv1.HTTPIngressPath{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPath:     \"/\",\n\t\t\t\t\t\t\tPathType: ptr.To(networkingv1.PathTypePrefix),\n\t\t\t\t\t\t\tBackend: networkingv1.IngressBackend{\n\t\t\t\t\t\t\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\t\t\t\t\t\t\tName: \"service-b\", // This one should be used\n\t\t\t\t\t\t\t\t\tPort: networkingv1.ServiceBackendPort{Name: testServicePortName},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tingress.Spec.DefaultBackend = &networkingv1.IngressBackend{\n\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\tName: \"service-a\", // This one should be ignored\n\t\t\tPort: networkingv1.ServiceBackendPort{Number: int32(testServicePortNum)},\n\t\t},\n\t}\n\n\tingressClass := newTestIngressClass()\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingress, serviceA, serviceB, ingressClass},\n\t\t[]runtime.Object{},\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. Sync\n\t_ = f.controller.syncHandler(f.ctx, key)\n\n\t// 3. Assert HTTPRoute was created\n\texpectedRouteName := generateRouteName(testIngressName, \"\") // \"\" host\n\troute, err := f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, expectedRouteName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get created HTTPRoute for default backend: %v\", err)\n\t}\n\n\t// 4. Assert Hostnames is nil\n\tif route.Spec.Hostnames != nil {\n\t\tt.Errorf(\"Default backend route should have nil Hostnames, got %v\", route.Spec.Hostnames)\n\t}\n\n\t// 5. Assert Rule points to service-b (proving precedence)\n\tif len(route.Spec.Rules) != 1 {\n\t\tt.Fatalf(\"Default backend route Rules: expected 1, got %d\", len(route.Spec.Rules))\n\t}\n\tbackendRef := route.Spec.Rules[0].BackendRefs[0]\n\tif string(backendRef.Name) != \"service-b\" {\n\t\tt.Errorf(\"BackendRef Name: expected 'service-b', got %s\", backendRef.Name)\n\t}\n}\n\n// === NEW TEST ===\nfunc TestSyncHandler_MultipleHostRules(t *testing.T) {\n\t// 1. Setup: One Ingress, two host rules.\n\tserviceA := newTestService(\"service-a\")\n\tserviceB := newTestService(\"service-b\")\n\tingressClass := newTestIngressClass()\n\n\tingress := newTestIngress(testIngressName)\n\tingress.Spec.Rules = []networkingv1.IngressRule{\n\t\t{\n\t\t\tHost: \"a.example.com\",\n\t\t\tIngressRuleValue: networkingv1.IngressRuleValue{\n\t\t\t\tHTTP: &networkingv1.HTTPIngressRuleValue{\n\t\t\t\t\tPaths: []networkingv1.HTTPIngressPath{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPath:     \"/\",\n\t\t\t\t\t\t\tPathType: ptr.To(networkingv1.PathTypePrefix),\n\t\t\t\t\t\t\tBackend: networkingv1.IngressBackend{\n\t\t\t\t\t\t\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\t\t\t\t\t\t\tName: \"service-a\",\n\t\t\t\t\t\t\t\t\tPort: networkingv1.ServiceBackendPort{Name: testServicePortName},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tHost: \"b.example.com\",\n\t\t\tIngressRuleValue: networkingv1.IngressRuleValue{\n\t\t\t\tHTTP: &networkingv1.HTTPIngressRuleValue{\n\t\t\t\t\tPaths: []networkingv1.HTTPIngressPath{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPath:     \"/\",\n\t\t\t\t\t\t\tPathType: ptr.To(networkingv1.PathTypePrefix),\n\t\t\t\t\t\t\tBackend: networkingv1.IngressBackend{\n\t\t\t\t\t\t\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\t\t\t\t\t\t\tName: \"service-b\",\n\t\t\t\t\t\t\t\t\tPort: networkingv1.ServiceBackendPort{Name: testServicePortName},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingress, serviceA, serviceB, ingressClass},\n\t\t[]runtime.Object{},\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. Sync\n\t_ = f.controller.syncHandler(f.ctx, key)\n\n\t// 3. Assert Route A was created\n\trouteNameA := generateRouteName(testIngressName, \"a.example.com\")\n\trouteA, err := f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, routeNameA, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get route for a.example.com: %v\", err)\n\t}\n\tif len(routeA.Spec.Hostnames) != 1 || routeA.Spec.Hostnames[0] != \"a.example.com\" {\n\t\tt.Errorf(\"Route A Hostnames: expected [\\\"a.example.com\\\"], got %v\", routeA.Spec.Hostnames)\n\t}\n\tif string(routeA.Spec.Rules[0].BackendRefs[0].Name) != \"service-a\" {\n\t\tt.Errorf(\"Route A Backend: expected 'service-a', got %s\", routeA.Spec.Rules[0].BackendRefs[0].Name)\n\t}\n\n\t// 4. Assert Route B was created\n\trouteNameB := generateRouteName(testIngressName, \"b.example.com\")\n\trouteB, err := f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, routeNameB, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get route for b.example.com: %v\", err)\n\t}\n\tif len(routeB.Spec.Hostnames) != 1 || routeB.Spec.Hostnames[0] != \"b.example.com\" {\n\t\tt.Errorf(\"Route B Hostnames: expected [\\\"b.example.com\\\"], got %v\", routeB.Spec.Hostnames)\n\t}\n\tif string(routeB.Spec.Rules[0].BackendRefs[0].Name) != \"service-b\" {\n\t\tt.Errorf(\"Route B Backend: expected 'service-b', got %s\", routeB.Spec.Rules[0].BackendRefs[0].Name)\n\t}\n}\n\n// === NEW TEST ===\nfunc TestSyncHandler_Update_StaleRouteDeletion(t *testing.T) {\n\t// 1. Setup:\n\t// - An Ingress for \"a.example.com\"\n\t// - A pre-existing, stale HTTPRoute for \"b.example.com\" that is *owned*\n\t//   by this Ingress (simulating a removed host rule).\n\tingress := newTestIngress(testIngressName)\n\tingress.Spec.Rules = []networkingv1.IngressRule{\n\t\t{\n\t\t\tHost: \"a.example.com\", // The ONLY desired host\n\t\t\tIngressRuleValue: networkingv1.IngressRuleValue{\n\t\t\t\tHTTP: &networkingv1.HTTPIngressRuleValue{\n\t\t\t\t\tPaths: []networkingv1.HTTPIngressPath{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPath:     \"/\",\n\t\t\t\t\t\t\tPathType: ptr.To(networkingv1.PathTypePrefix),\n\t\t\t\t\t\t\tBackend: networkingv1.IngressBackend{\n\t\t\t\t\t\t\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\t\t\t\t\t\t\tName: testServiceName,\n\t\t\t\t\t\t\t\t\tPort: networkingv1.ServiceBackendPort{Name: testServicePortName},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tstaleRouteName := generateRouteName(testIngressName, \"b.example.com\")\n\tstaleRoute := &gatewayv1.HTTPRoute{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      staleRouteName,\n\t\t\tNamespace: testNamespace,\n\t\t\tOwnerReferences: []metav1.OwnerReference{\n\t\t\t\t*metav1.NewControllerRef(ingress, networkingv1.SchemeGroupVersion.WithKind(\"Ingress\")),\n\t\t\t},\n\t\t},\n\t\tSpec: gatewayv1.HTTPRouteSpec{\n\t\t\tHostnames: []gatewayv1.Hostname{\"b.example.com\"},\n\t\t},\n\t}\n\n\tservice := newTestService(testServiceName)\n\tingressClass := newTestIngressClass()\n\n\tf := newTestFixture(t,\n\t\t[]runtime.Object{ingress, service, ingressClass},\n\t\t[]runtime.Object{staleRoute}, // Pre-create the stale route\n\t)\n\tdefer f.cancel()\n\n\tkey := fmt.Sprintf(\"%s/%s\", testNamespace, testIngressName)\n\n\t// 2. Sync\n\t_ = f.controller.syncHandler(f.ctx, key)\n\n\t// 3. Assert desired route (\"a\") was created\n\tdesiredRouteName := generateRouteName(testIngressName, \"a.example.com\")\n\t_, err := f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, desiredRouteName, metav1.GetOptions{})\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to get desired route: %v\", err)\n\t}\n\n\t// 4. Assert stale route (\"b\") was deleted\n\t_, err = f.gwClient.GatewayV1().HTTPRoutes(testNamespace).Get(f.ctx, staleRouteName, metav1.GetOptions{})\n\tif !errors.IsNotFound(err) {\n\t\tt.Errorf(\"Stale HTTPRoute should be deleted (IsNotFound), but got: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "pkg/loadbalancer/proxy.go",
    "content": "package loadbalancer\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"text/template\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\tv1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"k8s.io/klog/v2\"\n\tnetutils \"k8s.io/utils/net\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n)\n\n// keep in sync with dynamicFilesystemConfig\nconst (\n\tproxyConfigPath    = \"/home/envoy/envoy.yaml\"\n\tproxyConfigPathCDS = \"/home/envoy/cds.yaml\"\n\tproxyConfigPathLDS = \"/home/envoy/lds.yaml\"\n\tenvoyAdminPort     = 10000\n)\n\n// start Envoy with dynamic configuration by using files that implement the xDS protocol.\n// https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/configuration-dynamic-filesystem\nconst dynamicFilesystemConfig = `node:\n  cluster: cloud-provider-kind\n  id: cloud-provider-kind-id\n\ndynamic_resources:\n  cds_config:\n    resource_api_version: V3\n    path: /home/envoy/cds.yaml\n  lds_config:\n    resource_api_version: V3\n    path: /home/envoy/lds.yaml\n\nadmin:\n  access_log_path: /dev/stdout\n  address:\n    socket_address:\n      address: 0.0.0.0\n      port_value: 10000\n`\n\n// proxyConfigData is supplied to the loadbalancer config template\ntype proxyConfigData struct {\n\tHealthCheckPort int                    // is the same for all ServicePorts\n\tServicePorts    map[string]servicePort // key is the IP family and Port and Protocol to support MultiPort services\n\tSessionAffinity string\n\tSourceRanges    []sourceRange\n}\n\ntype sourceRange struct {\n\tPrefix string\n\tLength int\n}\n\ntype servicePort struct {\n\t// frontend\n\tListener endpoint\n\t// backend\n\tCluster []endpoint\n}\n\ntype endpoint struct {\n\tAddress  string\n\tPort     int\n\tProtocol string\n}\n\n// proxyLDSConfigTemplate is the loadbalancer config template for listeners\nconst proxyLDSConfigTemplate = `\nresources:\n{{- range $index, $servicePort := .ServicePorts }}\n- \"@type\": type.googleapis.com/envoy.config.listener.v3.Listener\n  name: listener_{{$index}}\n  address:\n    socket_address:\n      address: {{ $servicePort.Listener.Address }}\n      port_value: {{ $servicePort.Listener.Port }}\n      protocol: {{ $servicePort.Listener.Protocol }}\n  {{- if eq $servicePort.Listener.Protocol \"UDP\"}}\n  udp_listener_config:\n    downstream_socket_config:\n      max_rx_datagram_size: 9000\n  listener_filters:\n  - name: envoy.filters.udp_listener.udp_proxy\n    typed_config:\n      '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig\n      access_log:\n      - name: envoy.file_access_log\n        typed_config:\n          \"@type\": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\n      stat_prefix: udp_proxy\n      matcher:\n        on_no_match:\n          action:\n            name: route\n            typed_config:\n              '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route\n              cluster: cluster_{{$index}}\n      {{- if eq $.SessionAffinity \"ClientIP\"}}\n      hash_policies:\n        source_ip: true\n      {{- end}}\n      upstream_socket_config:\n        max_rx_datagram_size: 9000\n  {{- else }}\n  filter_chains:\n  - filters:\n    - name: envoy.filters.network.tcp_proxy\n      typed_config:\n        \"@type\": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\n        access_log:\n        - name: envoy.file_access_log\n          typed_config:\n            \"@type\": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\n        stat_prefix: tcp_proxy\n        cluster: cluster_{{$index}}\n        {{- if eq $.SessionAffinity \"ClientIP\"}}\n        hash_policy:\n          source_ip: {}\n        {{- end}}\n  {{- if len $.SourceRanges }}\n    filter_chain_match:\n      source_prefix_ranges:\n      {{- range $sr := $.SourceRanges }}\n      - address_prefix: \"{{ $sr.Prefix }}\"\n        prefix_len: {{ $sr.Length }}\n      {{- end }}\n  {{- end }}\n  {{- end}}\n{{- end }}\n`\n\n// proxyCDSConfigTemplate is the loadbalancer config template for clusters\n// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/health_check.proto#envoy-v3-api-msg-config-core-v3-healthcheck-httphealthcheck\nconst proxyCDSConfigTemplate = `\nresources:\n{{- range $index, $servicePort := .ServicePorts }}\n- \"@type\": type.googleapis.com/envoy.config.cluster.v3.Cluster\n  name: cluster_{{$index}}\n  connect_timeout: 3s\n  type: STATIC\n  common_lb_config:\n    healthy_panic_threshold:\n      value: 0\n  {{- if eq $.SessionAffinity \"ClientIP\"}}\n  lb_policy: RING_HASH\n  {{- else}}\n  lb_policy: RANDOM\n  {{- end}}\n  health_checks:\n  - timeout: 3s\n    interval: 2s\n    unhealthy_threshold: 2\n    healthy_threshold: 1\n    initial_jitter: 0s\n    no_traffic_interval: 3s\n    always_log_health_check_failures: true\n    always_log_health_check_success: true\n    event_log_path: /dev/stdout\n    http_health_check:\n      path: /healthz\n  load_assignment:\n    cluster_name: cluster_{{$index}}\n    endpoints:\n    {{- range $address := $servicePort.Cluster }}\n      - lb_endpoints:\n        - endpoint:\n            health_check_config:\n              port_value: {{ $.HealthCheckPort }}\n            address:\n              socket_address:\n                address: {{ $address.Address }}\n                port_value: {{ $address.Port }}\n                protocol: {{ $address.Protocol }}\n    {{- end}}\n{{- end }}\n`\n\n// proxyConfig returns a kubeadm config generated from config data, in particular\n// the kubernetes version\nfunc proxyConfig(configTemplate string, data *proxyConfigData) (config string, err error) {\n\tt, err := template.New(\"loadbalancer-config\").Parse(configTemplate)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to parse config template\")\n\t}\n\t// execute the template\n\tvar buff bytes.Buffer\n\terr = t.Execute(&buff, data)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"error executing config template\")\n\t}\n\treturn buff.String(), nil\n}\n\nfunc generateConfig(service *v1.Service, nodes []*v1.Node) *proxyConfigData {\n\tif service == nil {\n\t\treturn nil\n\t}\n\thcPort := 10256 // kube-proxy default port\n\tif service.Spec.ExternalTrafficPolicy == v1.ServiceExternalTrafficPolicyTypeLocal {\n\t\thcPort = int(service.Spec.HealthCheckNodePort)\n\t}\n\n\tlbConfig := &proxyConfigData{\n\t\tHealthCheckPort: hcPort,\n\t\tSessionAffinity: string(service.Spec.SessionAffinity),\n\t}\n\n\tservicePortConfig := map[string]servicePort{}\n\tfor _, ipFamily := range service.Spec.IPFamilies {\n\t\tfor _, port := range service.Spec.Ports {\n\t\t\tif port.Protocol != v1.ProtocolTCP && port.Protocol != v1.ProtocolUDP {\n\t\t\t\tklog.Infof(\"service port protocol %s not supported\", port.Protocol)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkey := fmt.Sprintf(\"%s_%d_%s\", ipFamily, port.Port, port.Protocol)\n\t\t\tbind := `0.0.0.0`\n\t\t\tif ipFamily == v1.IPv6Protocol {\n\t\t\t\tbind = `\"::\"`\n\t\t\t}\n\n\t\t\tbackends := []endpoint{}\n\t\t\tfor _, n := range nodes {\n\t\t\t\tfor _, addr := range n.Status.Addresses {\n\t\t\t\t\t// only internal IPs supported\n\t\t\t\t\tif addr.Type != v1.NodeInternalIP {\n\t\t\t\t\t\tklog.V(2).Infof(\"address type %s, only %s supported\", addr.Type, v1.NodeInternalIP)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// only addresses that match the Service IP family\n\t\t\t\t\tif (netutils.IsIPv4String(addr.Address) && ipFamily != v1.IPv4Protocol) ||\n\t\t\t\t\t\t(netutils.IsIPv6String(addr.Address) && ipFamily != v1.IPv6Protocol) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tbackends = append(backends, endpoint{Address: addr.Address, Port: int(port.NodePort), Protocol: string(port.Protocol)})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservicePortConfig[key] = servicePort{\n\t\t\t\tListener: endpoint{Address: bind, Port: int(port.Port), Protocol: string(port.Protocol)},\n\t\t\t\tCluster:  backends,\n\t\t\t}\n\t\t}\n\t}\n\tlbConfig.ServicePorts = servicePortConfig\n\n\tfor _, sr := range service.Spec.LoadBalancerSourceRanges {\n\t\t// This is validated (though the validation mistakenly allows whitespace)\n\t\t// so we don't bother dealing with parse failures.\n\t\t_, cidr, _ := netutils.ParseCIDRSloppy(strings.TrimSpace(sr))\n\t\tif cidr != nil {\n\t\t\tlen, _ := cidr.Mask.Size()\n\t\t\tlbConfig.SourceRanges = append(lbConfig.SourceRanges,\n\t\t\t\tsourceRange{\n\t\t\t\t\tPrefix: cidr.IP.String(),\n\t\t\t\t\tLength: len,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\tklog.V(2).Infof(\"envoy config info: %+v\", lbConfig)\n\treturn lbConfig\n}\n\n// TODO: move to xDS via GRPC instead of having to deal with files\nfunc proxyUpdateLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) error {\n\tif service == nil {\n\t\treturn nil\n\t}\n\tvar stdout, stderr bytes.Buffer\n\tname := loadBalancerName(clusterName, service)\n\tconfig := generateConfig(service, nodes)\n\t// create loadbalancer config data\n\tldsConfig, err := proxyConfig(proxyLDSConfigTemplate, config)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to generate loadbalancer config data\")\n\t}\n\n\tklog.V(2).Infof(\"updating loadbalancer with config %s\", ldsConfig)\n\terr = container.Exec(name, []string{\"cp\", \"/dev/stdin\", proxyConfigPathLDS + \".tmp\"}, strings.NewReader(ldsConfig), &stdout, &stderr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcdsConfig, err := proxyConfig(proxyCDSConfigTemplate, config)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to generate loadbalancer config data\")\n\t}\n\n\tklog.V(2).Infof(\"updating loadbalancer with config %s\", cdsConfig)\n\terr = container.Exec(name, []string{\"cp\", \"/dev/stdin\", proxyConfigPathCDS + \".tmp\"}, strings.NewReader(cdsConfig), &stdout, &stderr)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// envoy has an initialization process until starts to forward traffic\n\t// https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/operations/init#arch-overview-initialization\n\t// also wait for the healthchecks and \"no_traffic_interval\"\n\tcmd := fmt.Sprintf(`chmod a+rw /home/envoy/* && mv %s %s && mv %s %s`, proxyConfigPathCDS+\".tmp\", proxyConfigPathCDS, proxyConfigPathLDS+\".tmp\", proxyConfigPathLDS)\n\terr = container.Exec(name, []string{\"bash\", \"-c\", cmd}, nil, &stdout, &stderr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error updating configuration Stdout: %s Stderr: %s : %w\", stdout.String(), stderr.String(), err)\n\t}\n\treturn waitLoadBalancerReady(ctx, name, 30*time.Second)\n}\n\nfunc waitLoadBalancerReady(ctx context.Context, name string, timeout time.Duration) error {\n\tportmaps, err := container.PortMaps(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar authority string\n\tif config.DefaultConfig.ControlPlaneConnectivity == config.Direct {\n\t\tipv4, _, err := container.IPs(name)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tauthority = net.JoinHostPort(ipv4, strconv.Itoa(envoyAdminPort))\n\t} else {\n\t\tport, ok := portmaps[strconv.Itoa(envoyAdminPort)+\"/tcp\"]\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"envoy admin port %d not found, got %v\", envoyAdminPort, portmaps)\n\t\t}\n\t\tauthority = net.JoinHostPort(\"127.0.0.1\", port)\n\t}\n\n\thttpClient := http.DefaultClient\n\terr = wait.PollUntilContextTimeout(ctx, 1*time.Second, timeout, true, func(ctx context.Context) (done bool, err error) {\n\t\t// iptables port forwarding on localhost only works for IPv4\n\t\tresp, err := httpClient.Get(fmt.Sprintf(\"http://%s/ready\", authority))\n\t\tif err != nil {\n\t\t\tklog.V(2).Infof(\"unexpected error trying to get load balancer %s readiness :%v\", name, err)\n\t\t\treturn false, nil\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tklog.V(2).Infof(\"unexpected status code from load balancer %s expected LIVE got %d\", name, resp.StatusCode)\n\t\t\treturn false, nil\n\t\t}\n\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\tklog.V(2).Infof(\"unexpected error trying to get load balancer %s readiness :%v\", name, err)\n\t\t\treturn false, nil\n\t\t}\n\n\t\tresponse := strings.TrimSpace(string(body))\n\t\tif response != \"LIVE\" {\n\t\t\tklog.V(2).Infof(\"unexpected ready response from load balancer %s expected LIVE got %s\", name, response)\n\t\t\treturn false, nil\n\t\t}\n\t\treturn true, nil\n\t})\n\treturn err\n}\n"
  },
  {
    "path": "pkg/loadbalancer/proxy_test.go",
    "content": "package loadbalancer\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/lithammer/dedent\"\n\tv1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/intstr\"\n\t\"k8s.io/utils/ptr\"\n)\n\nfunc makeNode(name string, ip string) *v1.Node {\n\treturn &v1.Node{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: name,\n\t\t},\n\t\tSpec: v1.NodeSpec{},\n\t\tStatus: v1.NodeStatus{\n\t\t\tAddresses: []v1.NodeAddress{\n\t\t\t\t{Type: v1.NodeInternalIP, Address: ip},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc makeService(name string) *v1.Service {\n\treturn &v1.Service{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: name,\n\t\t},\n\t\tSpec: v1.ServiceSpec{\n\t\t\tType: v1.ServiceTypeClusterIP,\n\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t{Port: 80},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc Test_generateConfig(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\tservice *v1.Service\n\t\tnodes   []*v1.Node\n\t\twant    *proxyConfigData\n\t}{\n\t\t{\n\t\t\tname: \"empty\",\n\t\t},\n\t\t{\n\t\t\tname: \"simple service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"test\",\n\t\t\t\t},\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tType:                  v1.ServiceTypeLoadBalancer,\n\t\t\t\t\tExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal,\n\t\t\t\t\tIPFamilies:            []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   30000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tHealthCheckNodePort: 32000,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnodes: []*v1.Node{\n\t\t\t\tmakeNode(\"a\", \"10.0.0.1\"),\n\t\t\t\tmakeNode(\"b\", \"10.0.0.2\"),\n\t\t\t},\n\t\t\twant: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32000,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 30000, string(v1.ProtocolTCP)}, {\"10.0.0.2\", 30000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiport service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"test\",\n\t\t\t\t},\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tType:                  v1.ServiceTypeLoadBalancer,\n\t\t\t\t\tExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal,\n\t\t\t\t\tIPFamilies:            []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   30000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       443,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   31000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tHealthCheckNodePort: 32000,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnodes: []*v1.Node{\n\t\t\t\tmakeNode(\"a\", \"10.0.0.1\"),\n\t\t\t\tmakeNode(\"b\", \"10.0.0.2\"),\n\t\t\t},\n\t\t\twant: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32000,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 30000, string(v1.ProtocolTCP)}, {\"10.0.0.2\", 30000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t\t\"IPv4_443_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 443, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 31000, string(v1.ProtocolTCP)}, {\"10.0.0.2\", 31000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiport different protocol service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"test\",\n\t\t\t\t},\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tType:                  v1.ServiceTypeLoadBalancer,\n\t\t\t\t\tExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal,\n\t\t\t\t\tIPFamilies:            []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   30000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   31000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolUDP,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tHealthCheckNodePort: 32000,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnodes: []*v1.Node{\n\t\t\t\tmakeNode(\"a\", \"10.0.0.1\"),\n\t\t\t\tmakeNode(\"b\", \"10.0.0.2\"),\n\t\t\t},\n\t\t\twant: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32000,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 30000, string(v1.ProtocolTCP)}, {\"10.0.0.2\", 30000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t\t\"IPv4_80_UDP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolUDP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 31000, string(v1.ProtocolUDP)}, {\"10.0.0.2\", 31000, string(v1.ProtocolUDP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiport service ipv6\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"test\",\n\t\t\t\t},\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tType:                  v1.ServiceTypeLoadBalancer,\n\t\t\t\t\tExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal,\n\t\t\t\t\tIPFamilies:            []v1.IPFamily{v1.IPv6Protocol},\n\t\t\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   30000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       443,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   31000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tHealthCheckNodePort: 32000,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnodes: []*v1.Node{\n\t\t\t\tmakeNode(\"a\", \"2001:db2::3\"),\n\t\t\t\tmakeNode(\"b\", \"2001:db2::4\"),\n\t\t\t},\n\t\t\twant: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32000,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv6_80_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: `\"::\"`, Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"2001:db2::3\", 30000, string(v1.ProtocolTCP)}, {\"2001:db2::4\", 30000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t\t\"IPv6_443_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: `\"::\"`, Port: 443, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"2001:db2::3\", 31000, string(v1.ProtocolTCP)}, {\"2001:db2::4\", 31000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"session affinity\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"test\",\n\t\t\t\t},\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tType:                  v1.ServiceTypeLoadBalancer,\n\t\t\t\t\tExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster,\n\t\t\t\t\tIPFamilies:            []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   30000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tSessionAffinity: v1.ServiceAffinityClientIP,\n\t\t\t\t\tSessionAffinityConfig: &v1.SessionAffinityConfig{\n\t\t\t\t\t\tClientIP: &v1.ClientIPConfig{\n\t\t\t\t\t\t\t// FIXME: This is currently ignored\n\t\t\t\t\t\t\tTimeoutSeconds: ptr.To[int32](60),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tnodes: []*v1.Node{\n\t\t\t\tmakeNode(\"a\", \"10.0.0.1\"),\n\t\t\t},\n\t\t\twant: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 10256,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 30000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSessionAffinity: \"ClientIP\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"source ranges\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"test\",\n\t\t\t\t},\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tType:                  v1.ServiceTypeLoadBalancer,\n\t\t\t\t\tExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster,\n\t\t\t\t\tIPFamilies:            []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t\tPorts: []v1.ServicePort{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPort:       80,\n\t\t\t\t\t\t\tTargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: 8080},\n\t\t\t\t\t\t\tNodePort:   30000,\n\t\t\t\t\t\t\tProtocol:   v1.ProtocolTCP,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tLoadBalancerSourceRanges: []string{\n\t\t\t\t\t\t\"10.0.0.0/8\",\n\t\t\t\t\t\t// This is \"valid\".\n\t\t\t\t\t\t\" 192.168.0.0/16  \",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tnodes: []*v1.Node{\n\t\t\t\tmakeNode(\"a\", \"10.0.0.1\"),\n\t\t\t},\n\t\t\twant: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 10256,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80_TCP\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"10.0.0.1\", 30000, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSourceRanges: []sourceRange{\n\t\t\t\t\t{Prefix: \"10.0.0.0\", Length: 8},\n\t\t\t\t\t{Prefix: \"192.168.0.0\", Length: 16},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := generateConfig(tt.service, tt.nodes); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Logf(\"diff %+v\", cmp.Diff(got, tt.want))\n\t\t\t\tt.Errorf(\"generateConfig() = %+v,\\n want %+v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_proxyConfig(t *testing.T) {\n\ttests := []struct {\n\t\tname       string\n\t\ttemplate   string\n\t\tdata       *proxyConfigData\n\t\twantConfig string\n\t}{\n\t\t{\n\t\t\tname:     \"ipv4 CDS\",\n\t\t\ttemplate: proxyCDSConfigTemplate,\n\t\t\tdata: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32764,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 30497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 30497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t\t\"IPv4_443\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 443, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 31497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 31497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantConfig: `\n\t\t\t\tresources:\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.cluster.v3.Cluster\n\t\t\t\t  name: cluster_IPv4_443\n\t\t\t\t  connect_timeout: 3s\n\t\t\t\t  type: STATIC\n\t\t\t\t  common_lb_config:\n\t\t\t\t    healthy_panic_threshold:\n\t\t\t\t      value: 0\n\t\t\t\t  lb_policy: RANDOM\n\t\t\t\t  health_checks:\n\t\t\t\t  - timeout: 3s\n\t\t\t\t    interval: 2s\n\t\t\t\t    unhealthy_threshold: 2\n\t\t\t\t    healthy_threshold: 1\n\t\t\t\t    initial_jitter: 0s\n\t\t\t\t    no_traffic_interval: 3s\n\t\t\t\t    always_log_health_check_failures: true\n\t\t\t\t    always_log_health_check_success: true\n\t\t\t\t    event_log_path: /dev/stdout\n\t\t\t\t    http_health_check:\n\t\t\t\t      path: /healthz\n\t\t\t\t  load_assignment:\n\t\t\t\t    cluster_name: cluster_IPv4_443\n\t\t\t\t    endpoints:\n\t\t\t\t      - lb_endpoints:\n\t\t\t\t        - endpoint:\n\t\t\t\t            health_check_config:\n\t\t\t\t              port_value: 32764\n\t\t\t\t            address:\n\t\t\t\t              socket_address:\n\t\t\t\t                address: 192.168.8.2\n\t\t\t\t                port_value: 31497\n\t\t\t\t                protocol: TCP\n\t\t\t\t      - lb_endpoints:\n\t\t\t\t        - endpoint:\n\t\t\t\t            health_check_config:\n\t\t\t\t              port_value: 32764\n\t\t\t\t            address:\n\t\t\t\t              socket_address:\n\t\t\t\t                address: 192.168.8.3\n\t\t\t\t                port_value: 31497\n\t\t\t\t                protocol: TCP\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.cluster.v3.Cluster\n\t\t\t\t  name: cluster_IPv4_80\n\t\t\t\t  connect_timeout: 3s\n\t\t\t\t  type: STATIC\n\t\t\t\t  common_lb_config:\n\t\t\t\t    healthy_panic_threshold:\n\t\t\t\t      value: 0\n\t\t\t\t  lb_policy: RANDOM\n\t\t\t\t  health_checks:\n\t\t\t\t  - timeout: 3s\n\t\t\t\t    interval: 2s\n\t\t\t\t    unhealthy_threshold: 2\n\t\t\t\t    healthy_threshold: 1\n\t\t\t\t    initial_jitter: 0s\n\t\t\t\t    no_traffic_interval: 3s\n\t\t\t\t    always_log_health_check_failures: true\n\t\t\t\t    always_log_health_check_success: true\n\t\t\t\t    event_log_path: /dev/stdout\n\t\t\t\t    http_health_check:\n\t\t\t\t      path: /healthz\n\t\t\t\t  load_assignment:\n\t\t\t\t    cluster_name: cluster_IPv4_80\n\t\t\t\t    endpoints:\n\t\t\t\t      - lb_endpoints:\n\t\t\t\t        - endpoint:\n\t\t\t\t            health_check_config:\n\t\t\t\t              port_value: 32764\n\t\t\t\t            address:\n\t\t\t\t              socket_address:\n\t\t\t\t                address: 192.168.8.2\n\t\t\t\t                port_value: 30497\n\t\t\t\t                protocol: TCP\n\t\t\t\t      - lb_endpoints:\n\t\t\t\t        - endpoint:\n\t\t\t\t            health_check_config:\n\t\t\t\t              port_value: 32764\n\t\t\t\t            address:\n\t\t\t\t              socket_address:\n\t\t\t\t                address: 192.168.8.3\n\t\t\t\t                port_value: 30497\n\t\t\t\t                protocol: TCP\n\t\t\t\t`,\n\t\t},\n\t\t{\n\t\t\tname:     \"ipv4 LDS\",\n\t\t\ttemplate: proxyLDSConfigTemplate,\n\t\t\tdata: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32764,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 30497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 30497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t\t\"IPv4_443\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 443, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 31497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 31497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantConfig: `\n\t\t\t\tresources:\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.listener.v3.Listener\n\t\t\t\t  name: listener_IPv4_443\n\t\t\t\t  address:\n\t\t\t\t    socket_address:\n\t\t\t\t      address: 0.0.0.0\n\t\t\t\t      port_value: 443\n\t\t\t\t      protocol: TCP\n\t\t\t\t  filter_chains:\n\t\t\t\t  - filters:\n\t\t\t\t    - name: envoy.filters.network.tcp_proxy\n\t\t\t\t      typed_config:\n\t\t\t\t        \"@type\": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\n\t\t\t\t        access_log:\n\t\t\t\t        - name: envoy.file_access_log\n\t\t\t\t          typed_config:\n\t\t\t\t            \"@type\": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\n\t\t\t\t        stat_prefix: tcp_proxy\n\t\t\t\t        cluster: cluster_IPv4_443\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.listener.v3.Listener\n\t\t\t\t  name: listener_IPv4_80\n\t\t\t\t  address:\n\t\t\t\t    socket_address:\n\t\t\t\t      address: 0.0.0.0\n\t\t\t\t      port_value: 80\n\t\t\t\t      protocol: TCP\n\t\t\t\t  filter_chains:\n\t\t\t\t  - filters:\n\t\t\t\t    - name: envoy.filters.network.tcp_proxy\n\t\t\t\t      typed_config:\n\t\t\t\t        \"@type\": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\n\t\t\t\t        access_log:\n\t\t\t\t        - name: envoy.file_access_log\n\t\t\t\t          typed_config:\n\t\t\t\t            \"@type\": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\n\t\t\t\t        stat_prefix: tcp_proxy\n\t\t\t\t        cluster: cluster_IPv4_80\n\t\t\t`,\n\t\t},\n\t\t{\n\t\t\tname:     \"ipv4 CDS with affinity\",\n\t\t\ttemplate: proxyCDSConfigTemplate,\n\t\t\tdata: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32764,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 30497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 30497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSessionAffinity: \"ClientIP\",\n\t\t\t},\n\t\t\twantConfig: `\n\t\t\t\tresources:\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.cluster.v3.Cluster\n\t\t\t\t  name: cluster_IPv4_80\n\t\t\t\t  connect_timeout: 3s\n\t\t\t\t  type: STATIC\n\t\t\t\t  common_lb_config:\n\t\t\t\t    healthy_panic_threshold:\n\t\t\t\t      value: 0\n\t\t\t\t  lb_policy: RING_HASH\n\t\t\t\t  health_checks:\n\t\t\t\t  - timeout: 3s\n\t\t\t\t    interval: 2s\n\t\t\t\t    unhealthy_threshold: 2\n\t\t\t\t    healthy_threshold: 1\n\t\t\t\t    initial_jitter: 0s\n\t\t\t\t    no_traffic_interval: 3s\n\t\t\t\t    always_log_health_check_failures: true\n\t\t\t\t    always_log_health_check_success: true\n\t\t\t\t    event_log_path: /dev/stdout\n\t\t\t\t    http_health_check:\n\t\t\t\t      path: /healthz\n\t\t\t\t  load_assignment:\n\t\t\t\t    cluster_name: cluster_IPv4_80\n\t\t\t\t    endpoints:\n\t\t\t\t      - lb_endpoints:\n\t\t\t\t        - endpoint:\n\t\t\t\t            health_check_config:\n\t\t\t\t              port_value: 32764\n\t\t\t\t            address:\n\t\t\t\t              socket_address:\n\t\t\t\t                address: 192.168.8.2\n\t\t\t\t                port_value: 30497\n\t\t\t\t                protocol: TCP\n\t\t\t\t      - lb_endpoints:\n\t\t\t\t        - endpoint:\n\t\t\t\t            health_check_config:\n\t\t\t\t              port_value: 32764\n\t\t\t\t            address:\n\t\t\t\t              socket_address:\n\t\t\t\t                address: 192.168.8.3\n\t\t\t\t                port_value: 30497\n\t\t\t\t                protocol: TCP\n\t\t\t\t`,\n\t\t},\n\t\t{\n\t\t\tname:     \"ipv4 LDS with affinity\",\n\t\t\ttemplate: proxyLDSConfigTemplate,\n\t\t\tdata: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32764,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 30497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 30497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSessionAffinity: \"ClientIP\",\n\t\t\t},\n\t\t\twantConfig: `\n\t\t\t\tresources:\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.listener.v3.Listener\n\t\t\t\t  name: listener_IPv4_80\n\t\t\t\t  address:\n\t\t\t\t    socket_address:\n\t\t\t\t      address: 0.0.0.0\n\t\t\t\t      port_value: 80\n\t\t\t\t      protocol: TCP\n\t\t\t\t  filter_chains:\n\t\t\t\t  - filters:\n\t\t\t\t    - name: envoy.filters.network.tcp_proxy\n\t\t\t\t      typed_config:\n\t\t\t\t        \"@type\": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\n\t\t\t\t        access_log:\n\t\t\t\t        - name: envoy.file_access_log\n\t\t\t\t          typed_config:\n\t\t\t\t            \"@type\": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\n\t\t\t\t        stat_prefix: tcp_proxy\n\t\t\t\t        cluster: cluster_IPv4_80\n\t\t\t\t        hash_policy:\n\t\t\t\t          source_ip: {}\n\t\t\t`,\n\t\t},\n\t\t{\n\t\t\tname:     \"ipv4 LDS with source ranges\",\n\t\t\ttemplate: proxyLDSConfigTemplate,\n\t\t\tdata: &proxyConfigData{\n\t\t\t\tHealthCheckPort: 32764,\n\t\t\t\tServicePorts: map[string]servicePort{\n\t\t\t\t\t\"IPv4_80\": servicePort{\n\t\t\t\t\t\tListener: endpoint{Address: \"0.0.0.0\", Port: 80, Protocol: string(v1.ProtocolTCP)},\n\t\t\t\t\t\tCluster:  []endpoint{{\"192.168.8.2\", 30497, string(v1.ProtocolTCP)}, {\"192.168.8.3\", 30497, string(v1.ProtocolTCP)}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSourceRanges: []sourceRange{\n\t\t\t\t\t{Prefix: \"10.0.0.0\", Length: 8},\n\t\t\t\t\t{Prefix: \"192.168.0.0\", Length: 16},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantConfig: `\n\t\t\t\tresources:\n\t\t\t\t- \"@type\": type.googleapis.com/envoy.config.listener.v3.Listener\n\t\t\t\t  name: listener_IPv4_80\n\t\t\t\t  address:\n\t\t\t\t    socket_address:\n\t\t\t\t      address: 0.0.0.0\n\t\t\t\t      port_value: 80\n\t\t\t\t      protocol: TCP\n\t\t\t\t  filter_chains:\n\t\t\t\t  - filters:\n\t\t\t\t    - name: envoy.filters.network.tcp_proxy\n\t\t\t\t      typed_config:\n\t\t\t\t        \"@type\": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\n\t\t\t\t        access_log:\n\t\t\t\t        - name: envoy.file_access_log\n\t\t\t\t          typed_config:\n\t\t\t\t            \"@type\": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\n\t\t\t\t        stat_prefix: tcp_proxy\n\t\t\t\t        cluster: cluster_IPv4_80\n\t\t\t\t    filter_chain_match:\n\t\t\t\t      source_prefix_ranges:\n\t\t\t\t      - address_prefix: \"10.0.0.0\"\n\t\t\t\t        prefix_len: 8\n\t\t\t\t      - address_prefix: \"192.168.0.0\"\n\t\t\t\t        prefix_len: 16\n\t\t\t`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgotConfig, err := proxyConfig(tt.template, tt.data)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"proxyConfig() error = %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\twantConfig := dedent.Dedent(tt.wantConfig)\n\t\t\tif gotConfig != wantConfig {\n\t\t\t\tt.Logf(\"%s\", gotConfig)\n\t\t\t\tt.Errorf(\"proxyConfig() not expected\\n%v\", cmp.Diff(gotConfig, wantConfig))\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/loadbalancer/server.go",
    "content": "package loadbalancer\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\tv1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tcloudprovider \"k8s.io/cloud-provider\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/config\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/constants\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/tunnels\"\n)\n\ntype Server struct {\n\ttunnelManager *tunnels.TunnelManager\n}\n\nvar _ cloudprovider.LoadBalancer = &Server{}\n\nfunc NewServer() cloudprovider.LoadBalancer {\n\ts := &Server{}\n\n\tif config.DefaultConfig.LoadBalancerConnectivity == config.Tunnel {\n\t\ts.tunnelManager = tunnels.NewTunnelManager()\n\t}\n\treturn s\n}\n\nfunc (s *Server) GetLoadBalancer(ctx context.Context, clusterName string, service *v1.Service) (*v1.LoadBalancerStatus, bool, error) {\n\t// report status\n\tname := loadBalancerName(clusterName, service)\n\tipv4, ipv6, err := container.IPs(name)\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"failed to get container details\") {\n\t\t\treturn nil, false, nil\n\t\t}\n\t\treturn nil, false, err\n\t}\n\tstatus := &v1.LoadBalancerStatus{}\n\n\t// process Ports\n\tportStatus := []v1.PortStatus{}\n\tfor _, port := range service.Spec.Ports {\n\t\tportStatus = append(portStatus, v1.PortStatus{\n\t\t\tPort:     port.Port,\n\t\t\tProtocol: port.Protocol,\n\t\t})\n\t}\n\n\t// process IPs\n\tsvcIPv4 := false\n\tsvcIPv6 := false\n\tfor _, family := range service.Spec.IPFamilies {\n\t\tif family == v1.IPv4Protocol {\n\t\t\tsvcIPv4 = true\n\t\t}\n\t\tif family == v1.IPv6Protocol {\n\t\t\tsvcIPv6 = true\n\t\t}\n\t}\n\tif ipv4 != \"\" && svcIPv4 {\n\t\tstatus.Ingress = append(status.Ingress, v1.LoadBalancerIngress{\n\t\t\tIP:     ipv4,\n\t\t\tIPMode: ptr.To(v1.LoadBalancerIPModeProxy),\n\t\t\tPorts:  portStatus,\n\t\t})\n\t}\n\tif ipv6 != \"\" && svcIPv6 {\n\t\tstatus.Ingress = append(status.Ingress, v1.LoadBalancerIngress{\n\t\t\tIP:     ipv6,\n\t\t\tIPMode: ptr.To(v1.LoadBalancerIPModeProxy),\n\t\t\tPorts:  portStatus,\n\t\t})\n\t}\n\n\treturn status, true, nil\n}\n\nfunc (s *Server) GetLoadBalancerName(ctx context.Context, clusterName string, service *v1.Service) string {\n\treturn loadBalancerName(clusterName, service)\n}\n\nfunc (s *Server) EnsureLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) {\n\tname := loadBalancerName(clusterName, service)\n\tif !container.IsRunning(name) {\n\t\tklog.Infof(\"container %s for loadbalancer is not running\", name)\n\t\tif container.Exist(name) {\n\t\t\terr := container.Delete(name)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\tif !container.Exist(name) {\n\t\tklog.V(2).Infof(\"creating container for loadbalancer\")\n\t\terr := s.createLoadBalancer(clusterName, service, config.DefaultConfig.ProxyImage)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// update loadbalancer\n\tklog.V(2).Infof(\"updating loadbalancer\")\n\terr := s.UpdateLoadBalancer(ctx, clusterName, service, nodes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// on some platforms that run containers in VMs forward from userspace\n\tif s.tunnelManager != nil {\n\t\tklog.V(2).Infof(\"updating loadbalancer tunnels on userspace\")\n\t\terr = s.tunnelManager.SetupTunnels(loadBalancerName(clusterName, service))\n\t\tif err != nil {\n\t\t\tklog.ErrorS(err, \"error setting up tunnels\")\n\t\t}\n\t}\n\n\t// get loadbalancer Status\n\tklog.V(2).Infof(\"get loadbalancer status\")\n\tstatus, ok, err := s.GetLoadBalancer(ctx, clusterName, service)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"loadbalancer %s not found\", name)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn status, nil\n}\n\nfunc (s *Server) UpdateLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) error {\n\treturn proxyUpdateLoadBalancer(ctx, clusterName, service, nodes)\n}\n\nfunc (s *Server) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, service *v1.Service) error {\n\tcontainerName := loadBalancerName(clusterName, service)\n\tvar err1, err2 error\n\tif s.tunnelManager != nil {\n\t\terr1 = s.tunnelManager.RemoveTunnels(containerName)\n\t}\n\t// Before deleting the load balancer store the logs if required\n\tif config.DefaultConfig.EnableLogDump {\n\t\tfileName := path.Join(config.DefaultConfig.LogDir, service.Namespace+\"_\"+service.Name+\".log\")\n\t\tklog.V(2).Infof(\"storing logs for loadbalancer %s on %s\", containerName, fileName)\n\t\tif err := container.LogDump(containerName, fileName); err != nil {\n\t\t\tklog.Infof(\"error trying to store logs for load balancer %s : %v\", containerName, err)\n\t\t}\n\t}\n\terr2 = container.Delete(containerName)\n\treturn errors.Join(err1, err2)\n}\n\n// loadbalancer name is a unique name for the loadbalancer container\nfunc loadBalancerName(clusterName string, service *v1.Service) string {\n\th := sha256.New()\n\t_, err := io.WriteString(h, loadBalancerSimpleName(clusterName, service))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\thash := h.Sum(nil)\n\treturn fmt.Sprintf(\"%s-%x\", constants.ContainerPrefix, hash[:6])\n}\n\nfunc loadBalancerSimpleName(clusterName string, service *v1.Service) string {\n\treturn clusterName + \"/\" + service.Namespace + \"/\" + service.Name\n}\n\nfunc ServiceFromLoadBalancerSimpleName(s string) (clusterName string, service *v1.Service) {\n\tslices := strings.Split(s, \"/\")\n\tif len(slices) != 3 {\n\t\treturn\n\t}\n\tclusterName = slices[0]\n\tservice = &v1.Service{ObjectMeta: metav1.ObjectMeta{Namespace: slices[1], Name: slices[2]}}\n\treturn\n}\n\n// createLoadBalancer create a docker container with a loadbalancer\nfunc (s *Server) createLoadBalancer(clusterName string, service *v1.Service, image string) error {\n\tname := loadBalancerName(clusterName, service)\n\n\tnetworkName := constants.FixedNetworkName\n\tif n := os.Getenv(\"KIND_EXPERIMENTAL_DOCKER_NETWORK\"); n != \"\" {\n\t\tnetworkName = n\n\t}\n\n\targs := []string{\n\t\t\"--detach\", // run the container detached\n\t\t\"--tty\",    // allocate a tty for entrypoint logs\n\t\t// label the node with the cluster ID\n\t\t\"--label\", fmt.Sprintf(\"%s=%s\", constants.NodeCCMLabelKey, clusterName),\n\t\t// label the node with the load balancer name\n\t\t\"--label\", fmt.Sprintf(\"%s=%s\", constants.LoadBalancerNameLabelKey, loadBalancerSimpleName(clusterName, service)),\n\t\t// user a user defined docker network so we get embedded DNS\n\t\t\"--net\", networkName,\n\t\t\"--init=false\",\n\t\t\"--hostname\", name, // make hostname match container name\n\t\t// label the node with the role ID\n\t\t// running containers in a container requires privileged\n\t\t// NOTE: we could try to replicate this with --cap-add, and use less\n\t\t// privileges, but this flag also changes some mounts that are necessary\n\t\t// including some ones docker would otherwise do by default.\n\t\t// for now this is what we want. in the future we may revisit this.\n\t\t\"--privileged\",\n\t\t\"--restart=on-failure\",                           // to deal with the crash casued by https://github.com/envoyproxy/envoy/issues/34195\n\t\t\"--sysctl=net.ipv4.ip_forward=1\",                 // allow ip forwarding\n\t\t\"--sysctl=net.ipv4.conf.all.rp_filter=0\",         // disable rp filter\n\t\t\"--sysctl=net.ipv4.ip_unprivileged_port_start=1\", // Allow lower port numbers for podman (see https://github.com/containers/podman/blob/main/rootless.md for more info)\n\t}\n\n\tif isIPv6Service(service) {\n\t\targs = append(args, []string{\n\t\t\t\"--sysctl=net.ipv6.conf.all.disable_ipv6=0\", // enable IPv6\n\t\t\t\"--sysctl=net.ipv6.conf.all.forwarding=1\",   // allow ipv6 forwarding})\n\t\t}...)\n\t}\n\n\tif s.tunnelManager != nil ||\n\t\tconfig.DefaultConfig.LoadBalancerConnectivity == config.Portmap {\n\t\t// Forward the Service Ports to the host so they are accessible on Mac and Windows.\n\t\t// For single IP-family services, explicitly bind on the matching listen address to avoid\n\t\t// dual-stack host bindings that cause connection resets in environments where IPv6 is\n\t\t// advertised but not functional end-to-end (e.g. some GitHub Actions runners).\n\t\t// For dual-stack or unspecified services, publish without an explicit address.\n\t\t// See https://github.com/kubernetes-sigs/cloud-provider-kind/issues/387\n\t\tlistenAddress := listenAddressForService(service)\n\t\tfor _, port := range service.Spec.Ports {\n\t\t\tif port.Protocol != v1.ProtocolTCP && port.Protocol != v1.ProtocolUDP {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif listenAddress != \"\" {\n\t\t\t\thostPortBinding := net.JoinHostPort(listenAddress, fmt.Sprintf(\"%d\", port.Port))\n\t\t\t\targs = append(args, fmt.Sprintf(\"--publish=%s:%d/%s\", hostPortBinding, port.Port, port.Protocol))\n\t\t\t} else {\n\t\t\t\targs = append(args, fmt.Sprintf(\"--publish=%d/%s\", port.Port, port.Protocol))\n\t\t\t}\n\t\t}\n\t}\n\t// publish the admin endpoint\n\targs = append(args, fmt.Sprintf(\"--publish=%d/%s\", envoyAdminPort, v1.ProtocolTCP))\n\t// Publish all ports in the host in random ports\n\targs = append(args, \"--publish-all\")\n\n\tif service.Spec.LoadBalancerIP != \"\" {\n\t\targs = append(args, \"--ip\", service.Spec.LoadBalancerIP)\n\t}\n\n\targs = append(args, image)\n\t// we need to override the default envoy configuration\n\t// https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/configuration-dynamic-filesystem\n\t// envoy crashes in some circumstances, causing the container to restart, the problem is that the container\n\t// may come with a different IP and we don't update the status, we may do it, but applications does not use\n\t// to handle that the assigned LoadBalancerIP changes.\n\t// https://github.com/envoyproxy/envoy/issues/34195\n\tcmd := []string{\"bash\", \"-c\",\n\t\tfmt.Sprintf(`echo -en '%s' > %s && touch %s && touch %s && while true; do envoy -c %s && break; sleep 1; done`,\n\t\t\tdynamicFilesystemConfig, proxyConfigPath, proxyConfigPathCDS, proxyConfigPathLDS, proxyConfigPath)}\n\targs = append(args, cmd...)\n\tklog.V(2).Infof(\"creating loadbalancer with parameters: %v\", args)\n\terr := container.Create(name, args)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create continers %s %v: %w\", name, args, err)\n\t}\n\n\treturn nil\n}\n\nfunc isIPv6Service(service *v1.Service) bool {\n\tif service == nil {\n\t\treturn false\n\t}\n\tfor _, family := range service.Spec.IPFamilies {\n\t\tif family == v1.IPv6Protocol {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// listenAddressForService returns the host listen address to use when publishing\n// ports for a service. For single IP-family services it returns the corresponding\n// wildcard address (\"0.0.0.0\" or \"::\") so that Docker does not create spurious\n// dual-stack bindings. For dual-stack or unspecified services it returns \"\" so\n// the caller falls back to publishing without an explicit address.\nfunc listenAddressForService(service *v1.Service) string {\n\tvar hasIPv4, hasIPv6 bool\n\tfor _, family := range service.Spec.IPFamilies {\n\t\tswitch family {\n\t\tcase v1.IPv4Protocol:\n\t\t\thasIPv4 = true\n\t\tcase v1.IPv6Protocol:\n\t\t\thasIPv6 = true\n\t\t}\n\t}\n\tif hasIPv4 && !hasIPv6 {\n\t\treturn \"0.0.0.0\"\n\t}\n\tif hasIPv6 && !hasIPv4 {\n\t\treturn \"::\"\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "pkg/loadbalancer/server_test.go",
    "content": "package loadbalancer\n\nimport (\n\t\"testing\"\n\n\tv1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/constants\"\n)\n\nfunc TestIsIPv6Service(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tservice  *v1.Service\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"nil service\",\n\t\t\tservice:  nil,\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname: \"IPv4-only service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tIPFamilies: []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname: \"IPv6-only service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tIPFamilies: []v1.IPFamily{v1.IPv6Protocol},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname: \"dual-stack service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tIPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"no IPFamilies set\",\n\t\t\tservice:  &v1.Service{},\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tactual := isIPv6Service(test.service)\n\t\t\tif actual != test.expected {\n\t\t\t\tt.Errorf(\"expected %v, got %v\", test.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestListenAddressForService(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tservice  *v1.Service\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"no IPFamilies set\",\n\t\t\tservice:  &v1.Service{},\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname: \"IPv4-only service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tIPFamilies: []v1.IPFamily{v1.IPv4Protocol},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"0.0.0.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"IPv6-only service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tIPFamilies: []v1.IPFamily{v1.IPv6Protocol},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"::\",\n\t\t},\n\t\t{\n\t\t\tname: \"dual-stack service\",\n\t\t\tservice: &v1.Service{\n\t\t\t\tSpec: v1.ServiceSpec{\n\t\t\t\t\tIPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"\",\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tactual := listenAddressForService(test.service)\n\t\t\tif actual != test.expected {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", test.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestLoadBalancerName(t *testing.T) {\n\ttests := []struct {\n\t\tname        string\n\t\tcluster     string\n\t\tservice     *v1.Service\n\t\texpected    string\n\t\texpectedLen int\n\t}{\n\t\t{\n\t\t\tname:        \"simple\",\n\t\t\tcluster:     \"test-cluster\",\n\t\t\tservice:     &v1.Service{ObjectMeta: metav1.ObjectMeta{Namespace: \"test-namespace\", Name: \"test-service\"}},\n\t\t\texpected:    constants.ContainerPrefix + \"-11ab7482a104\",\n\t\t\texpectedLen: 20,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tactual := loadBalancerName(test.cluster, test.service)\n\t\t\tif actual != test.expected {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", test.expected, actual)\n\t\t\t}\n\t\t\tif len(actual) != test.expectedLen {\n\t\t\t\tt.Errorf(\"expected length %d, got %d\", test.expectedLen, len(actual))\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/provider/cloud.go",
    "content": "package provider\n\nimport (\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/constants\"\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/loadbalancer\"\n\n\tcloudprovider \"k8s.io/cloud-provider\"\n\n\t\"sigs.k8s.io/kind/pkg/cluster\"\n)\n\nfunc New(clusterName string, kindClient *cluster.Provider) cloudprovider.Interface {\n\treturn &cloud{\n\t\tclusterName:  clusterName,\n\t\tkindClient:   kindClient,\n\t\tlbController: loadbalancer.NewServer(),\n\t}\n}\n\nvar _ cloudprovider.Interface = (*cloud)(nil)\n\n// controller is the KIND implementation of the cloud provider interface\ntype cloud struct {\n\tclusterName  string // name of the kind cluster\n\tkindClient   *cluster.Provider\n\tlbController cloudprovider.LoadBalancer\n}\n\n// Initialize passes a Kubernetes clientBuilder interface to the cloud provider\nfunc (c *cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stopCh <-chan struct{}) {\n\t// noop\n}\n\n// Clusters returns the list of clusters.\nfunc (c *cloud) Clusters() (cloudprovider.Clusters, bool) {\n\treturn c, true\n}\n\n// ProviderName returns the cloud provider ID.\nfunc (c *cloud) ProviderName() string {\n\treturn constants.ProviderName\n}\n\nfunc (c *cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) {\n\treturn c, true\n}\n\nfunc (c *cloud) Instances() (cloudprovider.Instances, bool) {\n\treturn nil, false\n}\n\nfunc (c *cloud) Zones() (cloudprovider.Zones, bool) {\n\treturn nil, false\n}\n\nfunc (c *cloud) Routes() (cloudprovider.Routes, bool) {\n\treturn nil, false\n}\n\nfunc (c *cloud) HasClusterID() bool {\n\treturn len(c.clusterName) > 0\n}\n\nfunc (c *cloud) InstancesV2() (cloudprovider.InstancesV2, bool) {\n\treturn c, true\n}\n"
  },
  {
    "path": "pkg/provider/clusters.go",
    "content": "package provider\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tcloudprovider \"k8s.io/cloud-provider\"\n\t\"k8s.io/klog/v2\"\n)\n\nvar _ cloudprovider.Clusters = &cloud{}\n\n// ListClusters lists the names of the available clusters.\nfunc (c *cloud) ListClusters(ctx context.Context) ([]string, error) {\n\tklog.V(2).Infof(\"List clusters\")\n\treturn c.kindClient.List()\n}\n\n// Master gets back the address (either DNS name or IP address) of the master node for the cluster.\nfunc (c *cloud) Master(ctx context.Context, clusterName string) (string, error) {\n\tklog.V(2).Infof(\"Get master for %s\", clusterName)\n\tclusters, err := c.kindClient.List()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tfor _, cluster := range clusters {\n\t\tif cluster == clusterName {\n\t\t\treturn clusterName + \"-control-plane\", nil\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"cluster %s node found\", clusterName)\n}\n"
  },
  {
    "path": "pkg/provider/instances.go",
    "content": "package provider\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tv1 \"k8s.io/api/core/v1\"\n\tcloudprovider \"k8s.io/cloud-provider\"\n\t\"k8s.io/klog/v2\"\n\t\"sigs.k8s.io/kind/pkg/cluster/nodes\"\n)\n\nvar _ cloudprovider.InstancesV2 = (*cloud)(nil)\n\nvar errNodeNotFound = errors.New(\"node not found\")\n\n// InstanceExists returns true if the instance for the given node exists according to the cloud provider.\nfunc (c *cloud) InstanceExists(ctx context.Context, node *v1.Node) (bool, error) {\n\tklog.V(2).Infof(\"Check if instance %s exists\", node.Name)\n\t_, err := c.findNodeByName(node.Name)\n\tif err == nil {\n\t\treturn true, nil\n\t}\n\tif errors.Is(err, errNodeNotFound) {\n\t\treturn false, nil\n\t}\n\treturn false, err\n}\n\n// InstanceShutdown returns true of the container doesn't exist\nfunc (c *cloud) InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) {\n\tklog.V(2).Infof(\"Check if instance %s is shutdown\", node.Name)\n\t_, err := c.findNodeByName(node.Name)\n\tif err == nil {\n\t\treturn false, nil\n\t}\n\tif errors.Is(err, errNodeNotFound) {\n\t\treturn true, nil\n\t}\n\treturn false, err\n}\n\n// InstanceMetadata returns the instance's metadata. The values returned in InstanceMetadata are\n// translated into specific fields and labels in the Node object on registration.\nfunc (c *cloud) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) {\n\tklog.V(2).Infof(\"Check instance metadata for %s\", node.Name)\n\tn, err := c.findNodeByName(node.Name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tm := &cloudprovider.InstanceMetadata{\n\t\t// TODO: podman support\n\t\tProviderID:   fmt.Sprintf(\"kind://%s/kind/%s\", c.clusterName, n.String()), // providerID: kind://<cluster-name>/kind/<node-name>\n\t\tInstanceType: \"kind-node\",\n\t\tNodeAddresses: []v1.NodeAddress{\n\t\t\t{\n\t\t\t\tType:    v1.NodeHostName,\n\t\t\t\tAddress: n.String(),\n\t\t\t},\n\t\t},\n\t\tZone:   \"\",\n\t\tRegion: \"\",\n\t}\n\tipv4, ipv6, err := n.IP()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif ipv4 != \"\" {\n\t\tm.NodeAddresses = append(m.NodeAddresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: ipv4})\n\t}\n\tif ipv6 != \"\" {\n\t\tm.NodeAddresses = append(m.NodeAddresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: ipv6})\n\t}\n\tklog.V(2).Infof(\"instance metadata for %s: %#v\", node.Name, m)\n\treturn m, nil\n}\n\nfunc (c *cloud) findNodeByName(name string) (nodes.Node, error) {\n\tnodes, err := c.kindClient.ListNodes(c.clusterName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"no nodes founds\")\n\t}\n\tfor _, n := range nodes {\n\t\tif n.String() == name {\n\t\t\treturn n, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"node with name %s does not exist on cluster %s\", name, c.clusterName)\n}\n"
  },
  {
    "path": "pkg/provider/loadbalancer.go",
    "content": "package provider\n\nimport (\n\t\"context\"\n\n\tv1 \"k8s.io/api/core/v1\"\n\tcloudprovider \"k8s.io/cloud-provider\"\n\t\"k8s.io/klog/v2\"\n)\n\nvar _ cloudprovider.LoadBalancer = &cloud{}\n\n// GetLoadBalancer returns whether the specified load balancer exists, and if so, what its status is.\n// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager\nfunc (c *cloud) GetLoadBalancer(ctx context.Context, clusterName string, service *v1.Service) (status *v1.LoadBalancerStatus, exists bool, err error) {\n\tklog.V(2).Infof(\"Get LoadBalancer cluster: %s service: %s\", clusterName, service.Name)\n\treturn c.lbController.GetLoadBalancer(ctx, clusterName, service)\n}\n\n// GetLoadBalancerName returns the name of the load balancer.\nfunc (c *cloud) GetLoadBalancerName(ctx context.Context, clusterName string, service *v1.Service) string {\n\tklog.V(2).Infof(\"Get LoadBalancerNmae cluster: %s service: %s\", clusterName, service.Name)\n\treturn c.lbController.GetLoadBalancerName(ctx, clusterName, service)\n}\n\n// EnsureLoadBalancer creates a new load balancer 'name', or updates the existing one. Returns the status of the balancer\nfunc (c *cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) {\n\tklog.V(2).Infof(\"Ensure LoadBalancer cluster: %s service: %s\", clusterName, service.Name)\n\treturn c.lbController.EnsureLoadBalancer(ctx, clusterName, service, nodes)\n}\n\n// UpdateLoadBalancer updates hosts under the specified load balancer.\nfunc (c *cloud) UpdateLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) error {\n\tklog.V(2).Infof(\"Update LoadBalancer cluster: %s service: %s\", clusterName, service.Name)\n\treturn c.lbController.UpdateLoadBalancer(ctx, clusterName, service, nodes)\n}\n\n// EnsureLoadBalancerDeleted deletes the specified load balancer if it\n// exists, returning nil if the load balancer specified either didn't exist or\n// was successfully deleted.\nfunc (c *cloud) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, service *v1.Service) error {\n\tklog.V(2).Infof(\"Ensure LoadBalancer deleted cluster: %s service: %s\", clusterName, service.Name)\n\treturn c.lbController.EnsureLoadBalancerDeleted(ctx, clusterName, service)\n}\n"
  },
  {
    "path": "pkg/tunnels/address_darwin.go",
    "content": "//go:build darwin\n\npackage tunnels\n\nimport (\n\t\"os/exec\"\n)\n\nfunc AddIPToLocalInterface(ip string) (string, error) {\n\t// TODO: IPv6\n\toutput, err := exec.Command(\"ifconfig\", \"lo0\", \"alias\", ip, \"netmask\", \"255.255.255.255\").CombinedOutput()\n\treturn string(output), err\n}\n\nfunc RemoveIPFromLocalInterface(ip string) (string, error) {\n\t// delete the IP address\n\toutput, err := exec.Command(\"ifconfig\", \"lo0\", \"-alias\", ip).CombinedOutput()\n\treturn string(output), err\n}\n"
  },
  {
    "path": "pkg/tunnels/address_other.go",
    "content": "//go:build !windows && !darwin\n\npackage tunnels\n\nimport (\n\t\"os/exec\"\n)\n\nfunc AddIPToLocalInterface(ip string) (string, error) {\n\toutput, err := exec.Command(\"ip\", \"addr\", \"add\", ip, \"dev\", \"lo\").CombinedOutput()\n\treturn string(output), err\n}\n\nfunc RemoveIPFromLocalInterface(ip string) (string, error) {\n\toutput, err := exec.Command(\"ip\", \"addr\", \"del\", ip, \"dev\", \"lo\").CombinedOutput()\n\treturn string(output), err\n}\n"
  },
  {
    "path": "pkg/tunnels/address_windows.go",
    "content": "//go:build windows\n\npackage tunnels\n\nimport (\n\t\"os/exec\"\n)\n\nfunc AddIPToLocalInterface(ip string) (string, error) {\n\toutput, err := exec.Command(\"netsh\", \"interface\", \"ip\", \"add\", \"address\", \"loopback\", ip, \"255.255.255.255\").CombinedOutput()\n\treturn string(output), err\n}\n\nfunc RemoveIPFromLocalInterface(ip string) (string, error) {\n\toutput, err := exec.Command(\"netsh\", \"interface\", \"ip\", \"delete\", \"address\", \"loopback\", ip, \"255.255.255.255\").CombinedOutput()\n\treturn string(output), err\n}\n"
  },
  {
    "path": "pkg/tunnels/tunnel.go",
    "content": "package tunnels\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"sigs.k8s.io/cloud-provider-kind/pkg/container\"\n)\n\ntype TunnelManager struct {\n\tmu      sync.Mutex\n\ttunnels map[string]map[string]*tunnel // first key is the service namespace/name second key is the servicePort\n}\n\nfunc NewTunnelManager() *TunnelManager {\n\tt := &TunnelManager{\n\t\ttunnels: map[string]map[string]*tunnel{},\n\t}\n\treturn t\n}\n\nfunc (t *TunnelManager) SetupTunnels(containerName string) error {\n\t// get the portmapping from the container and its internal IPs and forward them\n\t// 1. Create the fake IP on the tunnel interface\n\t// 2. Capture the traffic directed to that IP port and forward to the exposed port in the host\n\tportmaps, err := container.PortMaps(containerName)\n\tif err != nil {\n\t\treturn err\n\t}\n\tklog.V(0).Infof(\"found port maps %v associated to container %s\", portmaps, containerName)\n\n\tipv4, _, err := container.IPs(containerName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tklog.V(0).Infof(\"setting IPv4 address %s associated to container %s\", ipv4, containerName)\n\t// check if the IP is already assigned to the local interface\n\tif !ipOnHost(ipv4) {\n\t\toutput, err := AddIPToLocalInterface(ipv4)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error adding IP to local interface: %w - %s\", err, output)\n\t\t}\n\t}\n\n\t// create tunnel from the ip:svcport to the localhost:portmap\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\t_, ok := t.tunnels[containerName]\n\tif !ok {\n\t\tt.tunnels[containerName] = map[string]*tunnel{}\n\t}\n\n\t// Reconcile: Remove tunnels that are not in portmaps\n\tfor containerPort, tun := range t.tunnels[containerName] {\n\t\tif _, ok := portmaps[containerPort]; !ok {\n\t\t\tklog.V(0).Infof(\"removing tunnel for %s %s as it is no longer in portmaps\", containerName, containerPort)\n\t\t\ttun.Stop() // nolint: errcheck\n\t\t\tdelete(t.tunnels[containerName], containerPort)\n\t\t}\n\t}\n\n\t// There is one IP per Service and a tunnel per Service Port\n\tfor containerPort, hostPort := range portmaps {\n\t\tparts := strings.Split(containerPort, \"/\")\n\t\tif len(parts) != 2 {\n\t\t\treturn fmt.Errorf(\"expected format port/protocol for container port, got %s\", containerPort)\n\t\t}\n\n\t\tif _, ok := t.tunnels[containerName][containerPort]; ok {\n\t\t\tklog.V(2).Infof(\"tunnel for %s %s already exists\", containerName, containerPort)\n\t\t\tcontinue\n\t\t}\n\n\t\ttun := NewTunnel(ipv4, parts[0], parts[1], \"localhost\", hostPort)\n\t\t// TODO check if we can leak tunnels\n\t\terr = tun.Start()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tt.tunnels[containerName][containerPort] = tun\n\t}\n\treturn nil\n}\n\nfunc (t *TunnelManager) RemoveTunnels(containerName string) error {\n\tklog.V(0).Infof(\"stopping tunnels on containers %s\", containerName)\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\ttunnels, ok := t.tunnels[containerName]\n\tif !ok {\n\t\treturn nil\n\t}\n\n\t// all tunnels in the same container share the same local IP on the host\n\tvar tunnelIP string\n\tfor _, tunnel := range tunnels {\n\t\tif tunnelIP == \"\" {\n\t\t\ttunnelIP = tunnel.localIP\n\t\t}\n\t\ttunnel.Stop() // nolint: errcheck\n\t}\n\tdelete(t.tunnels, containerName)\n\n\tklog.V(0).Infof(\"Removing IPv4 address %s associated to local interface\", tunnelIP)\n\toutput, err := RemoveIPFromLocalInterface(tunnelIP)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error removing IP from local interface: %w - %s\", err, output)\n\t}\n\treturn nil\n}\n\n// tunnel listens on localIP:localPort and proxies the connection to remoteIP:remotePort\ntype tunnel struct {\n\tlistener   net.Listener\n\tudpConn    *net.UDPConn\n\tudpDone    chan struct{}\n\tlocalIP    string\n\tlocalPort  string\n\tprotocol   string\n\tremoteIP   string // address:Port\n\tremotePort string\n}\n\nfunc NewTunnel(localIP, localPort, protocol, remoteIP, remotePort string) *tunnel {\n\treturn &tunnel{\n\t\tlocalIP:    localIP,\n\t\tlocalPort:  localPort,\n\t\tprotocol:   protocol,\n\t\tremoteIP:   remoteIP,\n\t\tremotePort: remotePort,\n\t}\n}\n\nfunc (t *tunnel) Start() error {\n\tklog.Infof(\"Starting tunnel on %s %s\", net.JoinHostPort(t.localIP, t.localPort), t.protocol)\n\tswitch t.protocol {\n\tcase \"udp\":\n\t\tlocalAddrStr := net.JoinHostPort(t.localIP, t.localPort)\n\t\tudpAddr, err := net.ResolveUDPAddr(\"udp4\", localAddrStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconn, err := net.ListenUDP(\"udp4\", udpAddr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// use a channel for signaling that the UDP connection has been closed\n\t\tt.udpDone = make(chan struct{})\n\t\tt.udpConn = conn\n\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase <-t.udpDone:\n\t\t\t\t\treturn\n\t\t\t\tdefault:\n\t\t\t\t}\n\n\t\t\t\terr = t.handleUDPConnection(conn)\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Infof(\"unexpected error on connection: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\tln, err := net.Listen(t.protocol, net.JoinHostPort(t.localIP, t.localPort))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tt.listener = ln\n\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tconn, err := ln.Accept()\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Infof(\"unexpected error listening: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttcpConn, ok := conn.(*net.TCPConn)\n\t\t\t\tif !ok {\n\t\t\t\t\tklog.Errorf(\"unexpected connection type %T, expected *net.TCPConn\", conn)\n\t\t\t\t\tconn.Close() // nolint: errcheck\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tgo func() {\n\t\t\t\t\terr := t.handleTCPConnection(tcpConn)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tklog.Infof(\"unexpected error on connection: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t}()\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported protocol %s\", t.protocol)\n\t}\n\treturn nil\n}\n\nfunc (t *tunnel) Stop() error {\n\tif t.listener != nil {\n\t\t_ = t.listener.Close()\n\t}\n\tif t.udpConn != nil {\n\t\t// Let the UDP handling code know that it can give up\n\t\tselect {\n\t\tcase <-t.udpDone:\n\t\tdefault:\n\t\t\tclose(t.udpDone)\n\t\t}\n\t\t_ = t.udpConn.Close()\n\t}\n\treturn nil\n}\n\nfunc (t *tunnel) handleTCPConnection(local *net.TCPConn) error {\n\ttcpAddr, err := net.ResolveTCPAddr(t.protocol, net.JoinHostPort(t.remoteIP, t.remotePort))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"can't resolve remote address %q: %v\", net.JoinHostPort(t.remoteIP, t.remotePort), err)\n\t}\n\tremote, err := net.DialTCP(t.protocol, nil, tcpAddr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"can't connect to server %q: %v\", net.JoinHostPort(t.remoteIP, t.remotePort), err)\n\t}\n\n\t// Fully close both connections on return.\n\tdefer remote.Close()\n\tdefer local.Close()\n\n\twg := &sync.WaitGroup{}\n\twg.Add(2)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tio.Copy(local, remote) // nolint: errcheck\n\t\t// Half-close the remote to local path.\n\t\tlocal.CloseWrite() // nolint: errcheck\n\t\tremote.CloseRead() // nolint: errcheck\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tio.Copy(remote, local) // nolint: errcheck\n\t\t// Half-close the local to remote path.\n\t\tremote.CloseWrite() // nolint: errcheck\n\t\tlocal.CloseRead()   // nolint: errcheck\n\t}()\n\n\twg.Wait()\n\treturn nil\n}\n\nfunc (t *tunnel) handleUDPConnection(conn *net.UDPConn) error {\n\tbuf := make([]byte, 1500)\n\tnRead, srcAddr, err := conn.ReadFromUDP(buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tklog.V(4).Infof(\"Read %d bytes from %s\", nRead, srcAddr.String())\n\n\tklog.V(4).Infof(\"Connecting to %s\", net.JoinHostPort(t.remoteIP, t.remotePort))\n\tremoteConn, err := net.Dial(\"udp4\", net.JoinHostPort(t.remoteIP, t.remotePort))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"can't connect to server %q: %v\", net.JoinHostPort(t.remoteIP, t.remotePort), err)\n\t}\n\tdefer remoteConn.Close()\n\n\tnWrite, err := remoteConn.Write(buf[:nRead])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fail to write to remote %s: %s\", remoteConn.RemoteAddr(), err)\n\t} else if nWrite < nRead {\n\t\tklog.V(2).Infof(\"Buffer underflow %d < %d to remote %s\", nWrite, nRead, remoteConn.RemoteAddr())\n\t}\n\tklog.V(4).Infof(\"Wrote %d bytes to to %s\", nWrite, remoteConn.RemoteAddr().String())\n\n\tbuf = make([]byte, 1500)\n\terr = remoteConn.SetReadDeadline(time.Now().Add(5 * time.Second)) // Add deadline to ensure it doesn't block forever\n\tif err != nil {\n\t\treturn fmt.Errorf(\"can not set read deadline: %v\", err)\n\t}\n\tnRead, err = remoteConn.Read(buf)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fail to read from remote %s: %s\", remoteConn.RemoteAddr(), err)\n\t}\n\tklog.V(4).Infof(\"Read %d bytes from %s\", nRead, remoteConn.RemoteAddr().String())\n\n\t_, err = conn.WriteToUDP(buf[:nRead], srcAddr)\n\n\treturn err\n}\n\nfunc ipOnHost(ip string) bool {\n\tifaces, err := net.Interfaces()\n\tif err != nil {\n\t\treturn false\n\t}\n\tfor _, i := range ifaces {\n\t\taddrs, err := i.Addrs()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, addr := range addrs {\n\t\t\tvar ipAddr net.IP\n\t\t\tswitch v := addr.(type) {\n\t\t\tcase *net.IPNet:\n\t\t\t\tipAddr = v.IP\n\t\t\tcase *net.IPAddr:\n\t\t\t\tipAddr = v.IP\n\t\t\t}\n\t\t\tif ipAddr != nil && ipAddr.String() == ip {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "tests/README.md",
    "content": "# Integration tests\n\n\n1. Install `bats` https://bats-core.readthedocs.io/en/stable/installation.html\n\n2. Install `kind` https://kind.sigs.k8s.io/\n\n3. Run the tests:\n```\nbats tests/\nbats tests/custom-network\n```"
  },
  {
    "path": "tests/custom-network/setup_suite.bash",
    "content": "#!/bin/bash\n\nset -eu\n\nfunction setup_suite {\n  export BATS_TEST_TIMEOUT=120\n  # Define the name of the kind cluster\n  export CLUSTER_NAME=\"ccm-kind-custom-network\"\n\n  export ARTIFACTS_DIR=\"$BATS_TEST_DIRNAME\"/../../_artifacts-custom-network\n  mkdir -p \"$ARTIFACTS_DIR\"\n  rm -rf \"$ARTIFACTS_DIR\"/*\n\n  # create custom docker network\n  export KIND_EXPERIMENTAL_DOCKER_NETWORK=kind-static\n  docker network create \\\n  --driver=bridge \\\n  --subnet=172.20.0.0/16 $KIND_EXPERIMENTAL_DOCKER_NETWORK\n\n  # create cluster\n  kind create cluster \\\n  --name $CLUSTER_NAME           \\\n  -v7 --wait 1m --retain --config=\"$BATS_TEST_DIRNAME/../kind.yaml\"\n\n  # build & run cloud-provider-kind\n  cd \"$BATS_TEST_DIRNAME\"/../.. && make\n  nohup \"$BATS_TEST_DIRNAME\"/../../bin/cloud-provider-kind -v 2 --enable-log-dumping --logs-dir \"$ARTIFACTS_DIR\" > \"$ARTIFACTS_DIR\"/ccm-kind.log 2>&1 &\n  export CCM_PID=$!\n\n  # test depend on external connectivity that can be very flaky\n  sleep 5\n}\n\nfunction teardown_suite {\n    kill \"$CCM_PID\"\n    kind export logs \"$ARTIFACTS_DIR\" --name \"$CLUSTER_NAME\"\n    kind delete cluster --name \"$CLUSTER_NAME\"\n    docker network rm \"$KIND_EXPERIMENTAL_DOCKER_NETWORK\"\n}"
  },
  {
    "path": "tests/custom-network/tests.bats",
    "content": "#!/usr/bin/env bats\n\n@test \"Static LoadBalancerIP\" {\n    # the static IP must be part of the custom docker network - calculate the .100 IP from the custom kind IPv4 network\n    SUBNET=$(docker network inspect $KIND_EXPERIMENTAL_DOCKER_NETWORK --format '{{range .IPAM.Config}}{{.Subnet}}{{\"\\n\"}}{{end}}' | grep -E '^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+')\n    STATIC_IP=$(echo \"$SUBNET\" | awk -F'[./]' '{printf \"%s.%s.%s.100\", $1, $2, $3}')\n\n    echo \"Using static IP: $STATIC_IP\"\n\n    TMP_YAML=$(mktemp)\n    sed \"s/REPLACE_WITH_STATIC_IP/$STATIC_IP/g\" \"$BATS_TEST_DIRNAME\"/../../examples/loadbalancer_static_ip.yaml > \"$TMP_YAML\"\n\n    kubectl apply -f \"$TMP_YAML\"\n    kubectl wait --for=condition=ready pods -l app=static-ip --timeout=60s\n\n    for i in {1..5}\n    do\n        IP=$(kubectl get services static-ip --output jsonpath='{.status.loadBalancer.ingress[0].ip}')\n        [[ ! -z \"$IP\" ]] && break || sleep 1\n    done\n\n    echo \"Assigned IP: $IP\"\n    [ \"$IP\" = \"$STATIC_IP\" ]\n\n    POD=$(kubectl get pod -l app=static-ip -o jsonpath='{.items[0].metadata.name}')\n    echo \"Pod $POD\"\n    for i in {1..5}\n    do\n        HOSTNAME=$(curl -s http://${IP}:80/hostname || true)\n        [[ ! -z \"$HOSTNAME\" ]] && break || sleep 1\n    done\n    echo \"Hostname via TCP: $HOSTNAME\"\n    [  \"$HOSTNAME\" = \"$POD\" ]\n\n    kubectl delete -f \"$TMP_YAML\"\n    rm \"$TMP_YAML\"\n}"
  },
  {
    "path": "tests/kind.yaml",
    "content": "kind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\nnodes:\n- role: control-plane\n- role: worker\n- role: worker\n"
  },
  {
    "path": "tests/setup_suite.bash",
    "content": "#!/bin/bash\n\nset -eu\n\nfunction setup_suite {\n  export BATS_TEST_TIMEOUT=120\n  # Define the name of the kind cluster\n  export CLUSTER_NAME=\"ccm-kind\"\n\n  export ARTIFACTS_DIR=\"$BATS_TEST_DIRNAME\"/../_artifacts\n  mkdir -p \"$ARTIFACTS_DIR\"\n  rm -rf \"$ARTIFACTS_DIR\"/*\n\n  # create cluster\n  kind create cluster --name $CLUSTER_NAME -v7 --wait 1m --retain --config=\"$BATS_TEST_DIRNAME/kind.yaml\"\n\n  cd \"$BATS_TEST_DIRNAME\"/.. && make\n  nohup \"$BATS_TEST_DIRNAME\"/../bin/cloud-provider-kind -v 2 --gateway-channel=standard --enable-log-dumping --logs-dir \"$ARTIFACTS_DIR\" > \"$ARTIFACTS_DIR\"/ccm-kind.log 2>&1 &\n  export CCM_PID=$!\n\n  # test depend on external connectivity that can be very flaky\n  sleep 5\n}\n\nfunction teardown_suite {\n    kill \"$CCM_PID\"\n    kind export logs \"$ARTIFACTS_DIR\" --name \"$CLUSTER_NAME\"\n    kind delete cluster --name \"$CLUSTER_NAME\"\n}"
  },
  {
    "path": "tests/tests.bats",
    "content": "#!/usr/bin/env bats\n\n@test \"ExternalTrafficPolicy: Local\" {\n    kubectl apply -f \"$BATS_TEST_DIRNAME\"/../examples/loadbalancer_etp_local.yaml\n    kubectl wait --for=condition=ready pods -l app=MyLocalApp\n    for i in {1..5}\n    do\n        IP=$(kubectl get services lb-service-local --output jsonpath='{.status.loadBalancer.ingress[0].ip}')\n        [[ ! -z \"$IP\" ]] && break || sleep 1\n    done\n    echo \"IP: $IP\"\n    POD=$(kubectl get pod -l app=MyLocalApp -o jsonpath='{.items[0].metadata.name}')\n    echo \"Pod $POD\"\n    for i in {1..5}\n    do\n        HOSTNAME=$(curl -s http://${IP}:80/hostname || true)\n        [[ ! -z \"$HOSTNAME\" ]] && break || sleep 1\n    done\n    echo \"Hostname via TCP: $HOSTNAME\"\n    [  \"$HOSTNAME\" = \"$POD\" ]\n    kubectl delete -f \"$BATS_TEST_DIRNAME\"/../examples/loadbalancer_etp_local.yaml\n}\n\n@test \"ExternalTrafficPolicy: Cluster\" {\n    kubectl apply -f \"$BATS_TEST_DIRNAME\"/../examples/loadbalancer_etp_cluster.yaml\n    kubectl wait --for=condition=ready pods -l app=MyClusterApp\n    for i in {1..5}\n    do\n        IP=$(kubectl get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')\n        [[ ! -z \"$IP\" ]] && break || sleep 1\n    done\n    echo \"IP: $IP\"\n    POD=$(kubectl get pod -l app=MyClusterApp -o jsonpath='{.items[0].metadata.name}')\n    echo \"Pod $POD\"\n    for i in {1..5}\n    do\n        HOSTNAME=$(curl -s http://${IP}:80/hostname || true)\n        [[ ! -z \"$HOSTNAME\" ]] && break || sleep 1\n    done\n    echo \"Hostname via TCP: $HOSTNAME\"\n    [  \"$HOSTNAME\" = \"$POD\" ]\n    kubectl delete -f \"$BATS_TEST_DIRNAME\"/../examples/loadbalancer_etp_cluster.yaml\n}\n\n@test \"Multiple Protocols: UDP and TCP\" {\n    kubectl apply -f \"$BATS_TEST_DIRNAME\"/../examples/loadbalancer_udp_tcp.yaml\n    kubectl wait --for=condition=ready pods -l app=multiprotocol\n    for i in {1..5}\n    do\n        IP=$(kubectl get services multiprotocol --output jsonpath='{.status.loadBalancer.ingress[0].ip}')\n        [[ ! -z \"$IP\" ]] && break || sleep 1\n    done\n    echo \"IP: $IP\"\n    POD=$(kubectl get pod -l app=multiprotocol -o jsonpath='{.items[0].metadata.name}')\n    echo \"Pod $POD\"\n    for i in {1..5}\n    do\n        HOSTNAME=$(curl -s http://${IP}:80/hostname || true)\n        [[ ! -z \"$HOSTNAME\" ]] && break || sleep 1\n    done\n    echo \"Hostname via TCP: $HOSTNAME\"\n    [  \"$HOSTNAME\" = \"$POD\" ]\n\n    for i in {1..5}\n    do\n        HOSTNAME=$(echo hostname | nc -u -w 3 ${IP} 80 || true)\n        [[ ! -z \"$HOSTNAME\" ]] && break || sleep 1\n    done\n    echo \"Hostname via UDP: $HOSTNAME\"\n    [[ ! -z \"$HOSTNAME\" ]] && [  \"$HOSTNAME\" = \"$POD\" ]\n    kubectl delete -f \"$BATS_TEST_DIRNAME\"/../examples/loadbalancer_udp_tcp.yaml\n}\n\n@test \"Simple Gateway\" {\n    # Apply the Gateway and HTTPRoute manifests\n    kubectl apply -f \"$BATS_TEST_DIRNAME\"/../examples/gateway_httproute_simple.yaml\n\n    # Wait for the backend application pod to be ready\n    kubectl wait --for=condition=ready pods -l app=MyApp --timeout=60s\n\n    # Retry loop to get the Gateway's external IP address\n    for i in {1..10}\n    do\n        # Fetch the IP address assigned by the load balancer to the Gateway\n        IP=$(kubectl get gateway prod-web --output jsonpath='{.status.addresses[0].value}' 2>/dev/null)\n        # Check if IP is not empty and break the loop if found\n        [[ ! -z \"$IP\" ]] && break || sleep 1\n    done\n    # Fail the test if IP is still empty after retries\n    if [[ -z \"$IP\" ]]; then\n      echo \"Failed to get Gateway IP address\"\n      return 1\n    fi\n    echo \"Gateway IP: $IP\"\n\n    # Get the name of the backend pod\n    POD=$(kubectl get pod -l app=MyApp -o jsonpath='{.items[0].metadata.name}')\n    echo \"Backend Pod: $POD\"\n\n    # Retry loop to curl the backend service through the Gateway IP\n    for i in {1..10}\n    do\n        # Curl the /hostname endpoint via the Gateway IP, ignore failures temporarily\n        HOSTNAME=$(curl -s --connect-timeout 5 http://${IP}:80/hostname || true)\n        # Check if HOSTNAME is not empty and break the loop if successful\n        [[ ! -z \"$HOSTNAME\" ]] && break || sleep 1\n    done\n     # Fail the test if HOSTNAME is still empty after retries\n    if [[ -z \"$HOSTNAME\" ]]; then\n      echo \"Failed to get hostname via Gateway\"\n      return 1\n    fi\n    echo \"Hostname via Gateway (TCP): $HOSTNAME\"\n\n    # Assert that the hostname returned by the service matches the actual pod name\n    [ \"$HOSTNAME\" = \"$POD\" ]\n\n    # Cleanup: Delete the applied manifests\n    kubectl delete --ignore-not-found -f \"$BATS_TEST_DIRNAME\"/../examples/gateway_httproute_simple.yaml\n}\n\n\n@test \"Ingress to Gateway Migration and X-Forwarded-For Header\" {\n    # Apply the Gateway and HTTPRoute manifests\n    kubectl apply -f \"$BATS_TEST_DIRNAME\"/../examples/ingress_foo_bar.yaml\n\n    # Wait for the backend application pod to be ready\n    kubectl wait --for=condition=ready pods -l app=foo --timeout=60s\n    kubectl wait --for=condition=ready pods -l app=foo --timeout=60s\n\n    # Give the controller time to reconcile\n    echo \"Waiting for reconciliation...\"\n    sleep 5\n\n    echo \"Finding Ingress Loadbalancer IP ...\"\n    run kubectl get ingress example-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}'\n    [ \"$status\" -eq 0 ]\n    export INGRESS_SVC_IP=\"$output\"\n    echo \"Ingress LoadBalancer IP: $INGRESS_SVC_IP\"\n\n    # Test /foo prefix\n    echo \"Testing /foo prefix (should match foo-app)...\"\n    run kubectl exec curl-pod -- curl -H \"Host: foo.example.com\" -s \"http://$INGRESS_SVC_IP/hostname\"\n    [ \"$status\" -eq 0 ]\n    [[ \"$output\" == \"foo-app\" ]]\n\n    # Test /bar prefix\n    echo \"Testing /bar prefix (should match bar-app)...\"\n    run kubectl exec curl-pod -- curl  -H \"Host: bar.example.com\" -s \"http://$INGRESS_SVC_IP/hostname\"\n    [ \"$status\" -eq 0 ]\n    [[ \"$output\" == \"bar-app\" ]]\n\n    # Test X-Forwarded-For header\n    echo \"Testing X-Forwarded-For header...\"\n    run kubectl exec curl-pod -- curl -H \"Host: foo.example.com\" -s \"http://$INGRESS_SVC_IP/header?key=X-Forwarded-For\"\n    [ \"$status\" -eq 0 ]\n    echo \"X-Forwarded-For header value: $output\"\n    [[ ! -z \"$output\" ]]\n\n    # Cleanup: Delete the applied manifests\n    kubectl delete --ignore-not-found -f \"$BATS_TEST_DIRNAME\"/../examples/ingress_foo_bar.yaml\n}\n\n@test \"Ingress WebSocket Support\" {\n    # 1. Deploy a WebSocket-capable echo server\n    cat <<EOF | kubectl apply -f -\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: ws-echo\n  labels:\n    app: ws-echo\nspec:\n  selector:\n    matchLabels:\n      app: ws-echo\n  template:\n    metadata:\n      labels:\n        app: ws-echo\n    spec:\n      containers:\n      - name: echo\n        image: jmalloc/echo-server\n        ports:\n        - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: ws-service\nspec:\n  ports:\n  - port: 80\n    targetPort: 8080\n  selector:\n    app: ws-echo\n---\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: ws-ingress\nspec:\n  rules:\n  - host: ws.example.com\n    http:\n      paths:\n      - path: /\n        pathType: Prefix\n        backend:\n          service:\n            name: ws-service\n            port:\n              number: 80\nEOF\n\n    # 2. Wait for the pod to be ready\n    kubectl wait --for=condition=ready pod -l app=ws-echo --timeout=60s\n\n    # 3. Get Ingress IP\n    echo \"Waiting for Ingress IP...\"\n    for i in {1..30}; do\n        IP=$(kubectl get ingress ws-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')\n        [[ ! -z \"$IP\" ]] && break || sleep 1\n    done\n    echo \"Ingress IP: $IP\"\n    [[ ! -z \"$IP\" ]]\n\n    # 4. Verify WebSocket Upgrade from the HOST (with retry)\n    echo \"Verifying WebSocket handshake...\"\n    FOUND=0\n    for i in {1..10}; do\n        # Use --max-time 3 to prevent hanging if the IP is not yet reachable\n        OUTPUT=$(curl -i -N -s --max-time 3 \\\n            -H \"Host: ws.example.com\" \\\n            -H \"Connection: Upgrade\" \\\n            -H \"Upgrade: websocket\" \\\n            -H \"Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==\" \\\n            -H \"Sec-WebSocket-Version: 13\" \\\n            \"http://$IP/\" || true)\n        \n        if [[ \"$OUTPUT\" == *\"101 Switching Protocols\"* ]]; then\n            echo \"Success: 101 Switching Protocols found\"\n            FOUND=1\n            break\n        fi\n        echo \"Attempt $i failed or not ready. Retrying...\"\n        sleep 1\n    done\n\n    if [ \"$FOUND\" -eq 0 ]; then\n        echo \"Failed to establish WebSocket connection. Last output:\"\n        echo \"$OUTPUT\"\n        return 1\n    fi\n\n    # Cleanup\n    kubectl delete deployment ws-echo\n    kubectl delete service ws-service\n    kubectl delete ingress ws-ingress\n}"
  }
]